我有一个简单的应用程序,在数据库和“多对多”关系中有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',则不要创建新号码,请使用现有号码。如果没有这样的数字,那么创建一个新数字并使用它。
答案 0 :(得分:5)
在employee.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
我找到了它的工作
答案 1 :(得分:4)
您可以使用rails验证来检查记录的唯一性。
在您的模型 phonenumber.rb 中添加以下内容
validates_uniqueness_of :column_name
它将确保 Phonenumber 仅具有唯一的phone_numbers。
现在在控制器中你可以从params检查phone_number,如果数字已经存在,那么我们将从params中删除嵌套属性,这样Phonenumber记录就不会生成。
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