我有以下型号:
class Activity < ActiveRecord::Base
has_many :clientships, :dependent => :destroy, :after_add => :default_client_info
accepts_nested_attributes_for :clientships, :allow_destroy => true
end
在我的控制器中,如果我执行以下操作
def new
@activity = IndividualActivity.new(params[:activity])
@activity.clientships.build(:client => Client.first)
...
end
然后保存表单,它会创建相关的参数并成功提交。
但是,如果我选择通过远程链接呼叫以下内容
@activity.clientships.build(:client => Client.last)
视图使用新的客户记录更新,但是当我提交表单时,不会为第二个嵌套属性创建参数[:activity]。 (为什么不呢? !?)的
这是观点:
%h1 Create a new Activity
- form_for @activity do |f|
%div
= render "activities/client_selector", :f => f
%div
= f.submit "Save!"
这是remote_link的控制器操作
def add_client
@activity = IndividualActivity.new(session[:individual_activity])
# Refresh client
@activity.clientships.build(:client => Client.find(params[:client_id]))
respond_to do |format|
format.js
end
end
这是add_client.html.js:
page.replace_html "selected_clients", :partial => 'activities/clients'
这是活动/客户部分:
- form_for @activity do |f|
- f.fields_for :clientships do |client_f|
%tr
%td= client_f.hidden_field :client_id
%td= client_f.object.client.full_name
有谁知道如何进一步解决这个问题?我的调试似乎已经走到了尽头......有一点需要注意,以下是form_for的双重用法用于new.html.haml和activities / clients partial(这有问题吗?)
- form_for @activity do |f|
我在rails v2.3.5
由于
答案 0 :(得分:1)
您询问有关调试的信息,因此第一步可能是查看服务器日志(log / development.log)。
你应该看到“params”哈希。 也许你的参数包含“activity”=&gt; {“client_id”=&gt; ..}而不是“client_id”=&gt; ..?
另请查看生成的HTML页面 - 使用Firebug或只使用浏览器的“查看源”方法。特别要注意输入名称。
如果一切正常,请在您的操作中添加一些调试调用,并查看development.log中的某些数据库活动 - SQL查询看起来像是在执行您想要的操作吗?
在您的问题中,没有“保存”方法。 'build'方法不保存创建的记录。也许这是你的问题?
def add_client
logger.debug "Creating Activity"
@activity = IndividualActivity.new(session[:individual_activity])
logger.debug "Building clientship"
# Refresh client
@activity.clientships.build(:client => Client.find(params[:client_id]))
logger.debug "@activity = #{@activity.inspect}"
# Maybe you were missing this part of code?
logger.debug "Saving @activity"
@activity.save! # use a ! to easily see any problems with saving.
# Remove in production and add a proper if
logger.debug "Saved. @activity = #{@activity.inspect}"
respond_to do |format|
format.js
end
end
您应该创建一个功能测试(如果您还没有),并确保如果您发送适当的参数,您的操作将按预期工作。
测试会缩小您的搜索范围。如果测试失败,您知道操作中存在问题。如果测试没问题,您需要确保正确发送参数,并且您可能在视图中遇到问题。
<强>更新强>: 你说你在页面上有两个表格。这可能是问题,因为一次只能发送一个表格。否则,它需要以一种可以在一个请求中发送两个请求的方式工作。
第一件事(在所有类似问题中都很有用):验证您的网页是否具有正确的HTML结构 - 例如http://validator.w3.org将是一个良好的开端。尝试使代码验证。我知道有些人将“绿色”状态视为无法实现的掌握,但实际上并非如此困难。使用有效的代码,您可以确定浏览器真正理解您的意思。
第二:将所有输入放在一个表单中。您有嵌套属性的问题。首先,尝试手动插入名称为<input name="activity[clientship_attributes][0][name]" value="John"/>
的输入,对于现有客户端,确保输入名称为activity[clientship_attributes][0][id]
。
这是处理嵌套属性的方式。
您的视图可能会自动创建此类字段。这个结构应该是你需要的:(它在我的一个旧的项目中使用rails 2.x,我刚刚用你使用的名称替换了名称)
<% form_for(@activity) do |f| %>
<p><%= f.text_field :activity_something %></p>
<% @activity.clientships.each do |clientship| %>
<% f.fields_for :clientships, clientship do |cform| %>
<p><%= cform.text_field :name %></p>
<p><%= cform.text_fiels :something %></p>
<% end %>
<% end %>
<% end %>
如果你真的想在那里使用部分,请不要在partial中创建新表单。仅使用上述代码的部分。
要将变量传递给partial,请在调用render的位置使用:locals属性:partial:
<%= render :partial => 'clientship', :locals => {:form => f} %>
然后,在您的部分内容中,您可以使用局部变量form
,在局部变量f
之外使用:locals => {:f => f}
。当然,您可以将变量映射到相同的名称:{{1}}