2016-07-13 29 views
0

這可能是完全解決這個問題的錯誤方式,我非常樂於接受替代方案。跳過has_many:通過無變化的模型創建

我有以下的模型,其中Users可以有很多Positions

class User < ApplicationRecord 
    has_many :user_positions 
    has_many :positions, through: :user_positions 

    accepts_nested_attributes_for :user_positions, 
    reject_if: :all_blank 
end 

class UserPosition < ApplicationRecord 
    belongs_to :user 
    belongs_to :position 
end 

class Position < ApplicationRecord 
end 

在我的編輯用戶的形式,我想允許User的當前位置進行更新。我這樣做,以下列方式:

<%= form_for @user do |f| %> 
    <%= f.label :name %> 
    <%= f.text_field :name %> 

    <%= f.fields_for :user_positions, @user.user_positions.order(created_at: :desc).first do |ff| %> 
    <%= ff.hidden_field :user_id, value: @user.id %> 
    <%= ff.collection_select :position_id, Position.all, :id, :label %> 
    <% end %> 

    <%= f.submit "Update User" %> 
<% end %> 

我遇到的問題是,UserPosition一個新實例被創建我每次提交表單時,即使這選擇的Position沒有改變。這會導致連接表中有大量重複條目,因爲當position_id的值發生更改時,我真的只關心「促銷」或「降級」。

我不想添加自定義驗證器來禁止創建,因爲我仍然希望表單能夠以未改變的位置提交。例如,我只想更改User的名稱。

有關如何處理此用例的任何建議?

回答

0

事實證明,您實際上可以使用任何方法作爲Symbol參數accepts_nested_attributes_forreject_if選項。

我更新了我的User型號如下,現在的行爲正是我想要的:

class User < ApplicationRecord 
    has_many :user_positions 
    has_many :positions, through: :user_positions 

    accepts_nested_attributes_for :user_positions, 
    reject_if: :same_as_previous_position 

    def same_as_previous_position(attributes) 
    if self.user_positions.empty? 
     return false 
    end 

    Position.find(attributes[:position_id]) == self.user_positions.order(created_at: :desc).first.position 
    end 
end