在 Rails 3 中使用带有嵌套路线的表单时出现问题

发布于 2024-10-27 22:51:28 字数 2481 浏览 4 评论 0原文

我有一个数据库结构,其中我的文章有很多人(通过联接,但工作正常)

我希望发生的是,当人们创建一篇文章时,他们可以同时创建新人

即路径应采用article/new/people/new形式。

事实上,在不使用嵌套路由的情况下,我通过使用这种方法进行了管理

article.rb(模型)

attr_accessor :new_person

articles_controller.rb

  def create
    @article = Article.new(params[:article])

    if params[:add_person]
      @person = Person.check_if_exists_or_create(@article.new_person["first_name"], @article.new_person["last_name"])
      if @person.save
        @article.people << @person
        @article.new_person = nil
      end
      render :action => "new" and return
    end
...

  end

form.erb

<%= form_for @article  do |f| %>
...

      <%= fields_for :new_person do |p| %>

        <% if @person && @person.errors.any? %>
          <%= render :partial => "shared/error_messages", :object => @person %>
        <% end %>

        <div class="field">
          <%= p.label :first_name, "First Name" %>
          <%= p.text_field :first_name %>
        </div>

        <div class="field">
          <%= p.label :last_name, "Last Name" %>
          <%= p.text_field :last_name %>
        </div>

        <%= submit_tag "Add Person", :name => "add_person" %>

      <% end %>
...
  <p>
    <%= f.submit %>
  </p>


<% end %>

这在一定程度上可以正常工作,但现在表单由于其他字段而变得更加复杂,我认为我可以重构它以利用嵌套路由。

此外,它还向创建控制器添加了很多逻辑 - 并且进一步深入,我可能会考虑将这些操作设为 javascript,在这种情况下,我知道确定控制器按下的特定按钮更加复杂。

出于这些原因,我认为嵌套路由方法可能更合适。

对于现有文章,它可以正常工作,例如/articles/1/people/new,没有任何问题。

我知道嵌套表单对于 html 验证原因来说是禁忌,所以我尝试了多种 form_for 和 fields_for 的组合来实现以下目标:

在articles/new页面上将

主表单提交到articles/new 将带有 new_person 字段的“子”表单提交到articles/new/people/new,

并尽可能轻松地由 UJS 进行更改

我认为我得到的最温暖的是这个错误

No route matches {:controller=>"people", :article_id=>#<Article id: nil, title: nil, published_on: nil, created_at: nil, updated_at: nil, people_count: nil, organizations_count: nil>}

,我猜问题就在那里此时没有与此人相关的article_id。

但事实上,我真正感兴趣的只是将该人添加到数据库中,然后创建与文章的关系,然后在保存整篇文章时存储该关系。

对长篇文章表示歉意,但希望我的问题更全面。

任何建议,包括更适合我的目标的替代方法,将不胜感激。 我观看了与嵌套表单和嵌套路线相关的铁路广播,并阅读了我在网上可以找到的所有内容,但尚未找到 /model/new/submodel/new 表单问题的解决方案。

非常感谢。

I have a database structure where my Articles have many People (through a join, but that is working fine)

What I would like to happen is that when people create an article they can at the same time create new people

Ie the path should be of the form article/new/people/new

In fact, without using nested routes I managed this by using this approach

article.rb (model)

attr_accessor :new_person

articles_controller.rb

  def create
    @article = Article.new(params[:article])

    if params[:add_person]
      @person = Person.check_if_exists_or_create(@article.new_person["first_name"], @article.new_person["last_name"])
      if @person.save
        @article.people << @person
        @article.new_person = nil
      end
      render :action => "new" and return
    end
...

  end

form.erb

<%= form_for @article  do |f| %>
...

      <%= fields_for :new_person do |p| %>

        <% if @person && @person.errors.any? %>
          <%= render :partial => "shared/error_messages", :object => @person %>
        <% end %>

        <div class="field">
          <%= p.label :first_name, "First Name" %>
          <%= p.text_field :first_name %>
        </div>

        <div class="field">
          <%= p.label :last_name, "Last Name" %>
          <%= p.text_field :last_name %>
        </div>

        <%= submit_tag "Add Person", :name => "add_person" %>

      <% end %>
...
  <p>
    <%= f.submit %>
  </p>


<% end %>

This works OK to an extent but now the form is becoming more complicated with other fields I thought I could refactor it to take advantage of nested routes.

Additionally, it is adding a lot of logic to the create controller - and further down to line I might consider making these actions javascript in which case I understand determining the specific button pressed by a controller is more complicated.

For these reasons I thought that a nested route approach might be a more natural fit.

For existing articles it works fine eg /articles/1/people/new with no problems.

I know that nesting forms is a no-no for html validation reasons among other things so I have tried numerous combinations of form_for and fields_for to achieve the goal of:

on the articles/new page

submitting the main form to articles/new
submitting the "sub" form with the new_person fields to articles/new/people/new

and making the change to doing this by UJS as painless as possible

The warmest I think I have got was with this error

No route matches {:controller=>"people", :article_id=>#<Article id: nil, title: nil, published_on: nil, created_at: nil, updated_at: nil, people_count: nil, organizations_count: nil>}

I am guessing that the issue is there is no article_id to relate the person to at that point.

But in fact I am only really interested in adding that person to the database and then creating a relationshop to the article which is then stored when the entire article is saved.

Apologies for the long post but wanted to be comprehensive in my question.

Any advice, including alternative approaches that would fit my objectives better would be much appreciated.
I have watched the railcasts relating to nested forms and nested routes and read all I can find online but haven't found a solution to the /model/new/submodel/new form issue.

Many thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文