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