2014-05-06 42 views
0

我有一個表foo其中belongs_to :barbarhas_many :foos)。Rails:通過候選鍵創建處理對象

有太多的foos爲它是明智的向用戶提供一個列表,當他們正在創建一個bar,所以我要得到用戶輸入的foo屬於bar的名稱。這個名字是一個候選關鍵字 - 保證是現在和唯一的。

我想我可以看到我需要採取的步驟:讓foo驗證bar_id存在,某處放了find_where來查找具有特定名稱的bar(如果它不存在,我會得到一個nil ,所以驗證應該失敗 - 很好)。

我想知道哪裏是最好的地方放find_where爲了檢查foo的所有創作和編輯,同時保持DRY原則?如何將它加入新的編輯表單? (還是有更多的Rails的方式?)

Rails 4,順便說一句。

編輯:

爲了使它更具體,假設我每天在世界機場的列表,在Airport,其中包含機場名稱(name),3個字符的標識符,被放在你的行李標籤(code)和Rails生成的airport_id。假設我有Departure其中belongs_to :airport。當我創建/編輯departure時,用戶進入機場code,我必須將其映射到Airport中的實際條目以創建/編輯條目。什麼是最好的地方/方式來做到這一點?

+0

我認爲你不應該在你的問題中使用'foo'或'bar'並將它們轉換爲更明智的例子......「這個問題中'foo'和'bar'的數量太高了」 –

回答

1

你實際上並不需要這麼做,Rails有辦法!當您在數據庫中兩個模型之間指定的關聯,只要簡單地將相關的型號名稱添加到驗證:

class Foo < ActiveRecord::Base 
    belongs_to :bar, validate: true 
end 

這將導致ActiveRecord的驗證問題的bar物體的存在。而且,因爲這是Rails的,有寫這種類型的驗證的其他方式:

隨着validates_associated

class Foo < ActiveRecord::Base 
    belongs_to :bar 
    validates_associated :bar 
end 

validates presence

class Foo < ActiveRecord::Base 
    belongs_to :bar, inverse_of :foo 
    validates :bar, presence: true 
end 

class Bar < ActiveRecord::Base 
    has_many :foo, inverse_of :bar 
end 

當心了幾個陷阱:

  • validates_associated建設,你必須確保只有規格如果您對兩個相關模型之一進行驗證。如果你在兩個屬性上都指定了validates_associated屬性,你的驗證將會無限地調用對方。
  • validates presence版本中,您必須指定inverse_of關係以驗證相關AR模型的存在。

編輯

在回答你的問題的編輯,我已經更新了我的答案:

你要查詢的Airportcode屬性,爲DeparturesController,下#create#update操作:

class DeparturesController < ApplicationController 

    def create 
    airport = Airport.find_by(code: params[:departure][:code]) 
    if airport 
     departure = airport.departures.build(params[:departure]) 
     if departure.save 
     ... 
     else 
     ... 
     end 
    else 
     ... 
    end 
    end 
end 

使用t他在ActiveRecord中的find_by方法是,如果搜索失敗,它將返回nil,這樣在用戶輸入無效代碼的情況下,您可以輕鬆編寫錯誤處理邏輯。

+0

謝謝,這簡化了驗證。這仍然留下了根據候選密鑰的用戶輸入來處理對'bar'的查找的最佳方式/位置的問題。 – digitig

+0

@digitig我有點困惑,你想要檢查什麼? – wvandaal

+0

你已經幫助了檢查位。我主要關心的是創作機制。 – digitig