【问题标题】:Rails nested form on HABTM: how to prevent duplicate entry?HABTM 上的 Rails 嵌套表单:如何防止重复输入?
【发布时间】:2013-06-06 05:38:14
【问题描述】:

我有一个简单的应用程序,在数据库中有 3 个表和“多对多”关系。

# Model Employee
class Employee < ActiveRecord::Base
   has_and_belongs_to_many :phonenumbers
   accepts_nested_attributes_for :phonenumbers, :allow_destroy => true
   attr_accessible :last_name, :first_name, :middle_name, :phonenumbers_attributes
end

# Model Phonenumber
class Phonenumber < ActiveRecord::Base
  has_and_belongs_to_many :employees
  attr_accessible :number
  accepts_nested_attributes_for :employees
end

我有 'employees_phonenumbers' 连接表,其中包含 'employee_id' 和 'phonenumber_id' 列。

# View
<%= form_for @employee, :url => { :action => :create } do |f| %>

<%= f.label "Last name"   %>
<%= f.text_field :last_name   %>

<%= f.label "First name"   %>
<%= f.text_field :first_name  %>

<%= f.label "Middle name"   %>
<%= f.text_field :middle_name %>

<%= f.fields_for :phonenumbers do |phonenumber| %>
    <%= phonenumber.label "Phone number" %>
    <%= phonenumber.telephone_field :number %>
<% end %>

<%= f.submit "Create" %>
<% end %>

# Controller
def create
  @employee = Employee.new(params[:employee])
  @employee.save ? (redirect_to :action => :index) : (render "new")
end

现在,如果我创建一个用户:“John”,电话号码为“555”,就可以了。

但如果我想创建一个具有相同电话号码“555”的用户“Larry”,则数据库中有一个重复的“555”条目。

如何防止这种情况发生?

更新:我的逻辑是:如果有数字'555',那么不要创建一个新的,使用现有的。如果没有这样的号码,则创建一个新号码并使用它。

【问题讨论】:

    标签: ruby-on-rails-3 forms validation activerecord


    【解决方案1】:

    在员工.rb 中:

    before_save :get_phonenumbers
    
    
      def get_phonenumbers
        self.phonenumbers = self.phonenumbers.collect do |phonenumber|
          Phonenumber.find_or_create_by_number(phonenumber.number)
        end
      end
    

    我发现它的工作原理

    【讨论】:

      【解决方案2】:

      您可以使用 rails 验证来检查记录的唯一性。

      在您的模型中 phonenumber.rb 放入以下行,

      validates_uniqueness_of :column_name
      

      这将确保 Phonenumber 将只有唯一的 phone_numbers。

      现在在控制器中,您可以从参数中检查电话号码,如果号码已经存在,那么我们将删除参数中的嵌套属性,这样电话号码记录就不会生成。

       def create
         @phone_number = Phonenumber.where(:number=>params[:employee][:phonenumber][:number])
         if @phone_number.any?
            params[:employee].delete(:phonenumber)
            @employee = Employee.new(params[:employee])
            if @employee.save?
              @employee.phonenumber = @phone_number.first
              redirect_to :action => :index
            else
              render "new"
            end
         else
           @employee = Employee.new(params[:employee])
           @employee.save ? (redirect_to :action => :index) : (render "new")
         end
       end
      

      【讨论】:

      • 我的逻辑是:如果有数字'555',那么不要创建一个新的,使用现有的。如果没有这样的号码,则创建一个新号码并使用它。
      • 您可以在创建记录之前检查电话号码是否存在。为此,您可以检查电话号码值表单参数。使用 binding.pry 检查 parmas 值并在 params 中进行相应更改。但是现在,让我先检查一下,以便我给你代码。
      • 我已经编辑了答案。请检查它,如果发生任何错误,请告诉我。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-24
      • 2016-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多