ruby on rails - How to access a model that belongs_to 2 models with all 3 models nested under another model? -
i'm modelling decision matrix, each decision (n of them), there x alternatives choose , y goals meet. each of x*y pairings of alternative , goal has score associated.
other documentation (listed below) has explained simpler modelling challenges, i'm still lost. how model decision matrix , use score attributes.
below code snippets of each model , test tried.
decisions
class decision < activerecord::base has_many :alternatives, dependent: :destroy has_many :goals, dependent: :destroy has_many :scores, dependent: :destroy validates :name, presence: true, length: { maximum: 50 } end
alternatives
class alternative < activerecord::base belongs_to :decision has_many :scores, dependent: :destroy validates :decision_id, presence: true validates :name, presence: true, length: { maximum: 50 } end
goals
class goal < activerecord::base belongs_to :decision has_many :scores, dependent: :destroy validates :decision_id, presence: true validates :name, presence: true, length: { maximum: 50 } validates :constraint, inclusion: [true, false] validates :rank, numericality: {only_integer: true, greater_than_or_equal_to: 1}, allow_blank: true validates :weight, numericality: {greater_than_or_equal_to: 0, less_than_or_equal_to: 1}, allow_blank: true end
score
class score < activerecord::base belongs_to :decision belongs_to :goal belongs_to :alternative validates :decision_id, presence: true validates :goal_id, presence: true validates :alternative_id, presence: true validates :rating, numericality: {only_integer: true, greater_than_or_equal_to: -2, less_than_or_equal_to: 2}, allow_blank: true end
i tried following test in decision_test.rb doesn't work, before realizing how difficult using score attributes be.
test "associated decision data should destroyed" @decision.save @alternative_1 = @decision.alternatives.create!(name: "toaster") @goal_1 = @decision.goals.create!(name: "fast") @score_1 = @decision.scores.build( params[:score].merge(:alternative_id => @alternative_1.id, :goal_id => @goal_1.id)) ## doesn't work assert_difference ['alternative.count','goal.count'], -1 @decision.destroy end end
schema.rb
activerecord::schema.define(version: 20150816211809) create_table "alternatives", force: :cascade |t| t.string "name" t.integer "decision_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.decimal "score" end add_index "alternatives", ["decision_id"], name: "index_alternatives_on_decision_id" create_table "decisions", force: :cascade |t| t.string "name" t.datetime "created_at", null: false t.datetime "updated_at", null: false end create_table "goals", force: :cascade |t| t.string "name" t.boolean "constraint", default: false t.integer "rank" t.decimal "weight" t.integer "decision_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false end add_index "goals", ["decision_id"], name: "index_goals_on_decision_id" create_table "scores", force: :cascade |t| t.integer "rating" t.decimal "value" t.integer "decision_id" t.integer "goal_id" t.integer "alternative_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false end add_index "scores", ["alternative_id"], name: "index_scores_on_alternative_id" add_index "scores", ["decision_id"], name: "index_scores_on_decision_id" add_index "scores", ["goal_id"], name: "index_scores_on_goal_id" end
resources (the relevant ones):
this might way of how go tackling this.
since each decision
has many alternatives
(x) , has many goals
(y), , these merely x,y pairings, pairings should stored join table. score
join table, represents alternativegoal
type join table, stores score value x,y join pair.
to decision link score manually create relationship when setting ids. hunch rails see relationship once been created. not ideal (syntax might off) think might work:
decision:
has_many :alternatives, dependent: :destroy has_many :goals, dependent: :destroy has_many :scores, dependent: :destroy, class: score
alternative:
has_many :goals, through: :scores
goal:
has_many :alternatives, through: :scores
score:
belongs_to :alternative belongs_to :goal
then execution along lines of:
@decision.save @alternative_1 = @decision.alternatives.create!(name: "toaster") @goal_1 = @decision.goals.create!(name: "fast") @score_1 = score.new(alternative_id: @alternative_1.id, goal_id: @goal_1.id, score: params[:score], decision_id: @decision.id) @score_1.save
then @decision.scores should work.
Comments
Post a Comment