场合
我正在尝试将多个电话号码绑定到has_and_belongs_to_many
的客户端。我可以添加客户端和电话号码。如果我拉出一个我有三个电话号码的客户端,它会显示每个号码,但是当我点击编辑时,它会在所有三个方框中显示三个输入框,而不是三个唯一的数字。
show.html.erb
显示所有三个数字。
<% @client.phones.each do |phone| %>
<tr>
<td><%= phone.number %></td>
<% end %>
_form.html.erb
单击编辑后,将显示三个文本输入框,所有三个框中的编号相同。
<% @client.phones.each do |phone| %>
<%=f.simple_fields_for @phone do |a| %>
<%=a.input :number %>
<% end %>
<% end %>
下面(与show.html.erb中的代码相同),这将显示所有三个唯一的数字,但它们会打印在屏幕上,显然不会出现在可以更改的输入框中。
<% @client.phones.each do |phone| %>
<tr>
<td><%= phone.number %></td>
<% end %>
clients_controller.erb
# GET /clients/1/edit
def edit
#Find client by id
@client = Client.find(params[:id])
@phone = Phone.find(@client.phone_ids)
end
# PATCH/PUT /clients/1
# PATCH/PUT /clients/1.json
def update
#Same as above, but if anything was changed, save the changes to the database
@client = Client.find(params[:id])
@phone = Phone.find(@client.phone_ids)
@phone = Phone.where(number: params[:client][:phone][:number]).first_or_create
@client.phones << @phone
respond_to do |format|
if @client.update(client_params)
format.html { redirect_to @client, notice: 'Client was successfully updated.' }
format.json { render :show, status: :ok, location: @client }
else
format.html { render :edit }
format.json { render json: @client.errors, status: :unprocessable_entity }
end
end
end
我的信念是我用每个新数字替换我的变量,因为它没有设置为数组。我开始尝试使用地图,但我还没有运气。
phone.map do |phone|
Phone.find(@client.phone_ids)
end
建议或见解map
是正确的方法,还是有其他我没有看到的东西?
答案 0 :(得分:0)
这两行导致了这个问题,因为您一遍又一遍地将找到或创建的手机添加到用户的手机中:
@phone = Phone.where(number: params[:client][:phone][:number]).first_or_create
@client.phones << @phone
取而代之的是:
def update
@client = Client.find(params[:id])
@phone = @client.phones.where(number: params[:client][:phone][:number]).first_or_create
respond_to do |format|
...
end
end
这将阻止您将来创建新的重复项。
此外,您_form.html.erb
中的拼写错误导致多次显示相同的电话号码:只需从@
移除<%= f.simple_fields_for @phone do |a| %>
,就应该只是
<%= f.simple_fields_for phone do |a| %>
要清理数据库中的重复项,您可以在rails console
中运行以下内容:
Client.all.each do |client|
uniq_numbers = client.phones.map(&:number).uniq
client.phones = numbers.map do |number|
Phone.where(number: number).first
end
end