代码之家  ›  专栏  ›  技术社区  ›  Jorge Israel Peña

Rails模型关联表单问题

  •  1
  • Jorge Israel Peña  · 技术社区  · 14 年前

    嘿,伙计们,我很难理解Rails的结构。我使用的是Rails 3,但我怀疑这是否是这个版本特有的。

    我有个模特, Goal 那个 has_many :commits Commit 模型 belongs_to :goal commits_table.references :goal .

    Rails Getting Started 指南,除了在那篇文章中他们使用 Post Comment 分别是。

    既然我已经描述了情况,我可以表达我的困惑。上 视图,我嵌入了一个表单来创建一个新的提交,该提交“附加”到当前查看的目标。这一切都很好。但是,我很难理解为什么我们要这样做

    <%= form_for([@goal, @goal.commits.build]) do |f| %>
    

    不是吗 form_for(@commit) ? 我明白我们为什么要 @goal commit_blah . Rails怎么知道的?我知道这是一个“信任和魔法”的完整系统,但我的意思是至少在高层,从这段代码暗示到Rails,我想要提交什么?

    我看了看 documentation 对于form,似乎其中一个参数可以是对form采取的操作。我想在这种情况下 @goal.commits.build 提交

    另外,为什么这些参数作为数组传递( [] )? 在Ruby中,该方法是否仍将其作为两个独立的参数,或者这是通过这种方式传递的原因?

    最后, rails generate 在显示另一个代码时自动给了我一些错误 _form.html.erb

    <% if @commit.errors.any? %>
      <div id="error_explanation">
        <h2><%= pluralize(@commit.errors.count, "error") %> prohibited this commit from being saved:</h2>
    
        <ul>
        <% @commit.errors.full_messages.each do |msg| %>
          <li><%= msg %></li>
        <% end %>
        </ul>
      </div>
    <% end %>
    

    如果我想把这个添加到这个嵌入的表单中,我该怎么做?我想我的问题是,我会用什么来代替 @commit ?

    谢谢。我只是想了解一下这些新概念。

    2 回复  |  直到 14 年前
        1
  •  1
  •   monocle    14 年前

    如果返回到文档并单击“显示源”,您将看到

    def form_for(record_or_name_or_array, *args, &proc)
      ...
      case record_or_name_or_array
      when String, Symbol
        ...
      when Array
        object = record_or_name_or_array.last
        object_name = options[:as] || ActiveModel::Naming.singular(object)
        apply_form_for_options!(record_or_name_or_array, options)
        args.unshift object
      else
        ...
      end
      ...
      output << fields_for(object_name, *(args << options), &proc)
      ...
    

    对于form_For,第一个参数可以是记录、名称或数组。在你的例子中,你给它一个数组。然后,代码将“object”确定为该数组的最后一个成员,即@goal.commits.build对象。对象名由 ActiveModel::Naming.singular

    console > ActiveModel::Naming.singular(@goal.commits.build)
    => "commit"
    

    然后它使用fields\u for和'commit'生成适当的表单字段。

        2
  •  0
  •   anotherdjohnson    14 年前

    看起来您正在使用嵌套资源。检查routes.rb文件,查看是否有以下内容:

    或者可能:

    map.resources:提交do |提交| commit.resources:目标

    如果是这种情况,则需要将commit和goal对象同时提供给form_for方法。