Rails显示HABTM工作,编辑HABTM显示最后一个条目的多个副本

时间:2014-12-22 23:56:53

标签: ruby-on-rails ruby block simple-form has-and-belongs-to-many

场合

我正在尝试将多个电话号码绑定到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是正确的方法,还是有其他我没有看到的东西?

1 个答案:

答案 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