![](/img/trans.png)
[英]How do I do a has_many through association on a has_many through association in rails?
[英]How do I update the record of a Has_Many through association?
我有三種模型- User
, Client
, Topic
。
用戶
has_many :clients
has_many :topics, :through => :clients, :uniq => true
客戶
has_and_belongs_to_many :topics
話題
has_and_belongs_to_many :clients
我想做的是在客戶端的edit
視圖上,更改此客戶端具有的主題。
這是我的客戶控制器的更新操作:
def update
if params[:topic_ids]
@client = current_user.clients.find(params[:id])
@client.topic_ids = params[:client][:topic_ids]
@client.save
else
@client = current_user.clients.find(params[:id])
end
respond_to do |format|
if @client.update_attributes(params[:client])
format.html { redirect_to @client, notice: 'Client was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @client.errors, status: :unprocessable_entity }
end
end
end
日志如下所示:
Started PUT "/clients/6" for 127.0.0.1 at 2012-10-07 18:56:14 -0500
Processing by ClientsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"J172mxxCX0OdxcGm4GSPv8=", "client"=>{"name"=>"Testeeee Johnson", "email"=>"testeee@johnson.com", "phone"=>"4320981234", "firm_id"=>"1", "personal_priority"=>"1", "last_contact"=>"2012-06-08", "vote"=>"1", "vote_for_user"=>"0", "next_vote"=>"2012-10-10", "vote_ii"=>"0", "vote_ii_for_us"=>"0"}, "topic_ids"=>["2"], "commit"=>"Update Client", "id"=>"6"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
Client Load (0.1ms) SELECT "clients".* FROM "clients" WHERE "clients"."user_id" = 1 AND "clients"."id" = ? LIMIT 1 [["id", "6"]]
Topic Load (0.2ms) SELECT "topics".* FROM "topics" INNER JOIN "clients_topics" ON "topics"."id" = "clients_topics"."topic_id" WHERE "clients_topics"."client_id" = 6
(0.1ms) begin transaction
(0.0ms) commit transaction
(0.0ms) begin transaction
(0.0ms) commit transaction
(0.0ms) begin transaction
(0.0ms) commit transaction
Redirected to http://localhost:3000/clients/6
Completed 302 Found in 8ms (ActiveRecord: 0.8ms)
不用說,它不會更新client.topics
的記錄。
如何更新客戶記錄的topics
屬性?
編輯1
_form
部分的外觀如下:
<%= form_for(@client) do |f| %>
<% if @client.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@client.errors.count, "error") %> prohibited this client from being saved:</h2>
<ul>
<% @client.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :email %><br />
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :firm %><br />
<%= f.select :firm_id, Firm.all.collect { |firm| [firm.name, firm.id] }, {:include_blank => 'None'} %>
</div>
<div class="field">
<h4>Topics</h4>
<% Topic.all.each do |topic| %>
<% checked = @client.topics.include?(topic) %>
<%= f.label(:name, topic.name) %> <%= check_box_tag "topic_ids[]", topic.id, checked %>
<% end %>
</div>
.
. - reduced for brevity
.
<br /><br />
<div class="actions">
<%= f.submit %>
</div>
<% end %>
無論出於何種原因, form
助手都不能與check_box
一起check_box
。
因此,這是有效的代碼:
<%= check_box_tag "client[topic_ids][]", topic.id, checked %>
根據針對類似問題的其他答案 ,輔助f.check_box
是模型綁定的,提供給復選框的值在表單上的模型中是隱式的。 問題是,我不知道如何獲取form_helper的隱式值以生成正確的標記,即client[topic_ids][]
,因此我不得不訴諸check_box_tag
。
您在下面的評論中提到,您還希望為每個主題添加權重。 has_and_belongs_to_many關聯不再支持此功能,因此,您應該使用has_many:through關聯:
class User < ActiveRecord::Base
has_many :clients
end
class Clients < ActiveRecord::Base
belongs_to :user
has_many :client_topics
has_many :topics, :through => :clients_topics
end
# Create this table like any other, with a "weight" field
class ClientsTopics < ActiveRecord::Base
belongs_to :client
belongs_to :topic
end
class Topics < ActiveRecord::Base
has_many :clients_topics
has_many :clients, :through => :clients_topics
end
現在,您的更新將需要刪除所有現有的clients_topics,然后遍歷傳遞的topic_id和權重,然后將其添加到客戶端,如下所示:
def update
if params[:topic_ids]
@client = current_user.clients.find(params[:id])
@client.clients_topics.delete_all
params[:client][:topic_ids].each_with_index do |topic_id, index|
weight = params[:client][:weights][index]
@client.clients_topics.create!(:topic_id => topic_id, :weight => weight)
end
else
@client = current_user.clients.find(params[:id])
end
(etc...)
end
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.