情况
我正在尝试将多个电话号码绑定到具有has_and_belongs_to_many
的客户。我可以添加客户和电话号码。如果我打开一个有三个电话号码的客户端,它会显示每个号码,但是当我单击编辑时,它会在所有三个框中显示三个具有相同数字的输入框,而不是三个唯一数字。
显示.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
是否是正确的方法,或者是否有其他我只是没有看到的东西?
这两行会导致问题,因为您一遍又一遍地将找到或创建的电话添加到用户的电话中:
@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