2016-04-14 59 views
0

我有一個簡單的關係:HAS_ONE/belongs_to的方法

Student 
has_one :locker, inverse_of: :student, validate: true, dependent: :nullify 
accepts_nested_attributes_for :locker 

Locker 
belongs_to :student, inverse_of: :locker, touch: true 

我有這樣一種形式:

<%= f.simple_fields_for :locker do |l| %> 
    <%= l.input :id, as: :select, 
     collection: @lockers_collection, 
     label: false, 
     value_method: :id, 
     label_method: :number, 
     include_blank: true, 
     input_html: { class: "admin-select2" }, 
     selected: "#{@student.locker ? @student.locker.id : ""}", 
     wrapper: 'admin_vertical_select' -%> 
<% end -%> 

當我創造新的學生,我可以分配一個儲物櫃(或沒有),一切都很簡單,並按預期工作。好吧,我不得不添加此兩輪牛車到學生的模式,否則Rails的在抱怨找不到記錄(解決方案在這裏發現了SO):

def locker_attributes=(attributes) 
    if attributes['id'].present? 
    self.locker = Locker.find(attributes['id']) 
    end 
    super 
end 

不管怎麼說,我有什麼重大的問題是編輯/更新動作。 首先,我需要檢查,如果學生目前有一個儲物櫃或不建現有的一個新的或:

if @student.locker 
    @student.build_locker(id: @student.locker.id) 
else 
    @student.build_locker 
end 

現在我試圖找到解決現實問題。 基本上有幾種情況可能發生:

  • 學生沒有儲物櫃,也沒有儲物櫃。
  • 學生有一個更衣室,但我想清除它

    在這兩種情況下的學生沒有更新,因爲(我懷疑)儲物櫃是空的。如何處理這個?

然後還有可能將Locker從一個更改爲另一個。 在這種情況下,我以某種方式認爲Rails將足夠聰明來更新「舊」儲物櫃。我可以看到old locker上的student_id id爲零,但Rails如何做到這一點?問題是我有一個關於Locker的paper_trail,我需要在舊版本變空時進行版本控制。

如何處理空方案?這是我最大的問題。 我是對的還是有更好的方法去做?

THX

回答

0

如果添加inverse_of您協會的車型,如:

  • 學生:has_one :locker, inverse_of: :student
  • 儲物櫃:belongs_to :student, inverse_of: :locker

您將能夠只使用:

@student.build_locker unless @student.locker 

而且您不需要def locker_attributes=(attributes)方法。

要廢掉你可以添加以下的動作在某些控制器,這樣在更衣室:

@student.locker = nil 
@student.save 
+0

嘿馬里奧。我實際上有inverse_of的定義,忘了提及它。我會更新我的問題。無論如何,沒有這種方法它就無法工作。 –

+0

更新了問題 –

+0

我不能只是取消並保存一個儲物櫃。如果學生的其他屬性發生了變化,該怎麼辦?像地址等... –