这可能是完全解决这个问题的错误方法,而且我对替代方案非常开放。
我有以下模型,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 :(得分:0)
事实证明,您实际上可以使用任何方法作为Symbol
accepts_nested_attributes_for
选项的reject_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