2015-08-17 60 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)的矩陣可以分開配置。

相關問題