【问题标题】:Rails 2.3.8 form_for partials not generating correct action urlRails 2.3.8 form_for partials 未生成正确的操作 url
【发布时间】:2010-08-29 19:23:33
【问题描述】:

嘿,我有一堆不同控制器的表单都在同一个页面上。这是因为有一堆模型相互堆叠,这是编辑它们的最佳方式。

我正在使用部分将每个表单包含到视图中,传递对象的本地参数和 form_for 使用的 url 参数

第一个(顶层)表单部分:

- form_for :person, local_assigns[:obj], :url => local_assigns[:url] do |person_form|
  = person_form.error_messages

  %p
    = person_form.label :first_name
    = person_form.text_field :first_name
  %p
    = person_form.label :last_name
    = person_form.text_field :last_name
  %p
    = person_form.submit 'Save'
    - if local_assigns[:obj]
      = link_to 'Destroy', local_assigns[:obj], :confirm => 'Are you sure?', :method => :delete

它被包含在视图中

= render :partial => 'person_form', :locals => { :url => { :controller => 'people', :action => 'create' }, :obj => @person }

创建一个新的人,并且

= render :partial => 'person_form', :locals => { :url => "people/update/#{person.id}", :obj => person }

在这个区块内:

- Person.all.each do |person|

编辑所有现有的人。

我的问题是,除了第一个(顶级)人员创建和编辑表单之外,每个表单都将操作设置为当前控制器。

所有其他表单的 form_for 部分都非常相似:

- form_for :day, local_assigns[:obj], local_assigns[:url] do |day_form|
  = day_form.error_messages

  %p
    = day_form.label :effective_date, 'Date'
    = day_form.datetime_select :effective_date
    = day_form.label :person_id
    = day_form.collection_select(:person_id, Person.all, :id, :full_name, { :selected => local_assigns[:ref] ? local_assigns[:ref].id : 1 } )
  %p
    = day_form.submit 'Save'
    - if local_assigns[:obj]
      = link_to 'Destroy', local_assigns[:obj], :confirm => 'Are you sure?', :method => :delete

通过

= render :partial => 'day_form', :locals => { :url => { :controller => 'days', :action => 'create' }, :obj => @day, :ref => person }

用于创建表单,并且

= render :partial => 'day_form', :locals => { :url => "days/update/#{day.id}", :obj => day, :ref => person }

用于编辑表单。

Person 和 Day 这两个模型通过拥有多个 :days 的 Person 和属于 :person 的 Day 连接在一起。关联都设置正确并且工作正常,问题在于使用不同的控制器渲染所有表单以生成正确的操作 url。

有什么建议吗?

(顺便说一句,我正在使用haml)

【问题讨论】:

  • pastie.org/1124904, pastie.org/1124916 展示做我想要完成的事情的正确方法。控制器可能看起来像 def update;garage = Garage.find(params[:id]);garage.update(params[:garage]);end

标签: ruby-on-rails


【解决方案1】:

你的语法对我来说有点奇怪。如果将实际对象传递给form_for,它会根据它是新记录还是现有记录自动确定将表单提交到哪里。

这样的事情应该可以为您解决问题:

# In your controller
# Create a new record
@new_person = Person.new
# And pull out all existing records for editing
@all_people = Person.all


# In whatever view is wrapping your form partials
%h1 Create a new person
= render :partial => 'person_form', :locals => { :person => @new_person }

%h1 Or edit any of the existing people
= render :partial => 'person_form', :collection => @all_people, :as => :person


# In your `person_form` partial
form_for person do |person_form|
  ... # your usual code here

在最后一行代码中,您调用 form_for,您传入一个实际对象 - 提交表单的 URL 是根据记录是否是新记录来推断的(就像 @new_person 一样)或已经存在于数据库中(就像@all_people 中的每个人一样)。

这有意义吗?我是否正确理解了这个问题?

【讨论】:

    【解决方案2】:

    如果PersonDay 被指定为路由中的资源,form_for 可以从对象中推断出正确的控制器和操作。比如……

    在你的个人部分:

    - form_for @person do |f|
      = f.error_messages
      = # ...etc...
    

    在你的一天部分(Person has_many Days):

    - form_for [@person, @day] do |f|
      = f.error_messages
      = # ...etc...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-25
      • 1970-01-01
      • 2013-06-15
      • 2016-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多