如何访问包含 belongs_to 2 个模型且所有 3 个模型都嵌套在另一个模型下的模型?
How to access a model that belongs_to 2 models with all 3 models nested under another model?
我正在对决策矩阵建模,因此对于每个 决策(其中的 n 个),有 x 备选方案 可供选择和 y 目标 达成。备选方案和目标的每个 x*y 对都有一个 Score 关联。
其他文档(在下面列出)已经解释了更简单的建模挑战,所以我仍然迷路了。我如何对决策矩阵建模并使用分数属性。
下面是每个模型的代码片段和我尝试过的测试。
决定
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
备选方案
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
目标
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
得分
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
我在 decision_test.rb 中尝试了以下测试,但没有用,然后才意识到使用 Score 属性会有多么困难。
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
资源(最相关的):
- http://guides.rubyonrails.org/association_basics.html
- http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
- Rails belongs_to many models
- can model "belong_to" two other models and have a nested relationship?
- Rails: New entry to a model that belongs_to two other
这可能是解决此问题的一种方法。
因为每个 Decision
有很多 Alternatives
(x) 和很多 Goals
(y),并且这些只是 X,Y 配对,这些配对应该存储为连接table。 Score
是这个连接 table,因为它本质上代表了一个 AlternativeGoal
类型的连接 table,只是它还存储了 X,Y 连接对的得分值。
要获得 link 评分的决定,您只需在设置 ID 时手动创建关系。我的直觉是 rails 将在关系创建后看到它。不理想(语法可能关闭)但我认为这可能有效:
决定:
has_many :alternatives, dependent: :destroy
has_many :goals, dependent: :destroy
has_many :scores, dependent: :destroy, class: Score
选择:
has_many :goals, through: :scores
目标:
has_many :alternatives, through: :scores
得分:
belongs_to :alternative
belongs_to :goal
那么你的执行将是这样的:
@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
那么@decision.scores应该可以了。
我倾向于同意 scores
模型并不像目前那样完全起作用。很难通过调用其他相关模型来创建它的实例。我会为您提出改进建议。
我相信 decision
、alternative
和 goal
之间的关系以适当的方式建模。
我建议您将模型 score
与其他模型分开。 score
class 应该不会 belong_to
其他机型。其他机型不要配置has_many :scores
您 schemar.rb
中的 table scores
可以在您拥有的状态下使用。
然后您可以在其他三个模型上创建一个 scores
函数,它会为您检索 score
模型,例如:
在 Decisions
模型中
def scores
Score.where(decision_id:self.id)
end
在 Alternatives
模型中
def scores
Score.where(decision_id:self.decision.id,alternative_id:self.id)
end
在 Goals
模型中
def scores
Score.where(decision_id:self.decision.id,goal_id:self.id)
end
这样可以单独配置包含评分系统 (scores
) 的矩阵。
我正在对决策矩阵建模,因此对于每个 决策(其中的 n 个),有 x 备选方案 可供选择和 y 目标 达成。备选方案和目标的每个 x*y 对都有一个 Score 关联。
其他文档(在下面列出)已经解释了更简单的建模挑战,所以我仍然迷路了。我如何对决策矩阵建模并使用分数属性。
下面是每个模型的代码片段和我尝试过的测试。
决定
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
备选方案
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
目标
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
得分
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
我在 decision_test.rb 中尝试了以下测试,但没有用,然后才意识到使用 Score 属性会有多么困难。
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
资源(最相关的):
- http://guides.rubyonrails.org/association_basics.html
- http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
- Rails belongs_to many models
- can model "belong_to" two other models and have a nested relationship?
- Rails: New entry to a model that belongs_to two other
这可能是解决此问题的一种方法。
因为每个 Decision
有很多 Alternatives
(x) 和很多 Goals
(y),并且这些只是 X,Y 配对,这些配对应该存储为连接table。 Score
是这个连接 table,因为它本质上代表了一个 AlternativeGoal
类型的连接 table,只是它还存储了 X,Y 连接对的得分值。
要获得 link 评分的决定,您只需在设置 ID 时手动创建关系。我的直觉是 rails 将在关系创建后看到它。不理想(语法可能关闭)但我认为这可能有效:
决定:
has_many :alternatives, dependent: :destroy
has_many :goals, dependent: :destroy
has_many :scores, dependent: :destroy, class: Score
选择:
has_many :goals, through: :scores
目标:
has_many :alternatives, through: :scores
得分:
belongs_to :alternative
belongs_to :goal
那么你的执行将是这样的:
@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
那么@decision.scores应该可以了。
我倾向于同意 scores
模型并不像目前那样完全起作用。很难通过调用其他相关模型来创建它的实例。我会为您提出改进建议。
我相信 decision
、alternative
和 goal
之间的关系以适当的方式建模。
我建议您将模型 score
与其他模型分开。 score
class 应该不会 belong_to
其他机型。其他机型不要配置has_many :scores
您 schemar.rb
中的 table scores
可以在您拥有的状态下使用。
然后您可以在其他三个模型上创建一个 scores
函数,它会为您检索 score
模型,例如:
在 Decisions
模型中
def scores
Score.where(decision_id:self.id)
end
在 Alternatives
模型中
def scores
Score.where(decision_id:self.decision.id,alternative_id:self.id)
end
在 Goals
模型中
def scores
Score.where(decision_id:self.decision.id,goal_id:self.id)
end
这样可以单独配置包含评分系统 (scores
) 的矩阵。