2015-08-17 61 views
0

我建模决策矩阵,因此每个决策(其中N),有x个替代可供选择和y 目标见面。替代方案和目标的每个x * y配对都有得分相关联。如何访问所有3个模型都属于另一个模型的belongs_to 2个模型?

其他文档(下面列出)解释了更简单的建模挑战,所以我仍然迷失。我如何模型决策矩阵使用分数属性

下面是每个模型的代码片段和我试过的一个测试。

决定

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 

在我意识到使用Score属性有多困难之前,我在decision_test.rb中尝试了下列不起作用的测试。

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 

资源(最相关的):

+0

你不介意加入你的问题“schema.rb”创建脚本表“算账”? –

+0

看起来你可能想要在这里使用多态关系,更新的'accep_nested_attributes'形式,或者涉及'has_many ...:through'类型的语法。我们确实需要查看您的模式以了解您所得到的结果,因为我怀疑您没有以这种方式构建好数据结构。 – Kelseydh

+0

谢谢@TheFabio。我已经在上面添加了它。 – purplengineer

回答

0

这可能是如何去解决此问题的方法。

由于每个Decision有许多Alternatives(x)并且有许多Goals(y),并且这些只是X,Y配对,所以这些配对应该存储为连接表。 Score是这个连接表,因为它基本上代表AlternativeGoal类型的连接表,只有它也存储X,Y连接对的分数值。

要获得决定链接到分数,您只需在设置ID时手动创建关系。我的预感是,铁轨一旦创建就会看到关系。不理想(语法可能会关闭),但我认为这可能工作:

决定:

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应该工作。

+1

谢谢!我用您提出的模式替换了我的Decision,Goal,Alternative和Score模型,但是在我进行的所有27项测试中失败了。也许我错过了一些东西,但决定取消这些变化。在我原来的情况下,我直接输入了“@ score_1 = Score.new(alternative_id:.......,rating:0”)和我的参数(“rating”属性),我的测试通过了! – purplengineer

0

我倾向于同意scores模型是不完全的功能是目前的方式。通过调用其他相关模型很难创建它的实例。我会建议你的改进。

我相信decision,alternativegoal之间的关系是以适当的方式建模的。

我建议你从其他部分分离score建模。 score类别不应该belong_to其他型号。而其他型号不应配置为has_many :scores

您的schemar.rb表中的表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)的矩阵可以分开配置。

相关问题