I'm modelling a decision matrix, so for each Decision (n of them), there are x Alternatives to choose from and y Goals to meet. Each of x*y pairings of Alternative and Goal has a Score associated.
Other documentation (listed below) has explained simpler modelling challenges, so I'm still lost. How do I model the decision matrix and use Score attributes.
Below are code snippets of each model and a test I 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 the following test in decision_test.rb that doesn't work, before realizing how difficult using Score attributes would be.
test "associated decision data should be destroyed" do
@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 do
@decision.destroy
end
end
Schema.rb
ActiveRecord::Schema.define(version: 20150816211809) do
create_table "alternatives", force: :cascade do |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 do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "goals", force: :cascade do |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 do |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 most relevant ones):