【问题标题】:Rails 4 has_one association form not buildingRails 4 has_one 关联表单未建立
【发布时间】:2013-11-06 03:46:01
【问题描述】:

我需要一些关于 Rails 4 如何使用 has_one 和 belongs_to 关联的指示。

我的表单没有保存has_one 关系

后模型

class Post < ActiveRecord::Base
  validates: :body, presence: true

  has_one :category, dependent: :destroy
  accepts_nested_attributes_for :category
end

class Category < ActiveRecord::Base
  validates :title, presence: true
  belongs_to :post
end

后控制器

class PostController < ApplicationController
  def new
    @post = Post.new
    @post.build_category
  end

  def create
    @post = Post.new(post_params)
  end

  private

  def post_params
    params.require(:post).permit(:body)
  end
end

Post#new 操作中的表单

<%= form_for @post do |form| %>

  <%= form.label :body %>
  <%= form.text_area :body %>

  <%= fields_for :category do |category_fields| %>
    <%= category_fields.label :title %>
    <%= category_fields.text_field :title %>
  <% end %>

  <%= form.button "Add Post" %>

<% end %>

提交 Post 表单时不会保存 category 标题。

调试参数

utf8: ✓
authenticity_token: 08/I6MsYjNUhzg4W+9SWuvXbSdN7WX2x6l2TmNwRl40=
post: !ruby/hash:ActionController::Parameters
  body: 'The best ice cream sandwich ever'
category: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
  title: 'Cold Treats'
button: ''
action: create
controller: posts

应用日志

Processing by BusinessesController#create as HTML
  Parameters: {"utf8"=>"✓",
               "authenticity_token"=>"08/I6MsYjNUhzg4W+9SWuvXbSdN7WX2x6l2TmNwRl40=",
               "post"=>{"body"=>"The best ice cream sandwich ever"},
               "category"=>{"title"=>"Cold Treats", "button"=>""}

在 Rails 控制台中.. 我可以成功运行以下命令

> a = Post.new
=> #<Post id: nil, body: "">
> a.category
=> nil

> b = Post.new
=> #<Post id: nil, body: "">
> b.build_category
=> #<Post id: nil, title: nil>
> b.body = "The best ice cream sandwich ever"
=> "The best ice cream sandwich ever"
> b.category.title = "Cold Treats"
=> "Cold Treats"

我的问题与如何解决这个问题有关:

  1. 不知道是不是一定要在post_params强参数方法中加上:category_attributes
  2. 日志和调试参数是否应该显示Category 属性 是否嵌套在 Post 参数中?
  3. Category 散列参数中有一个空白的button 键不在我的fields_for 中使用表单助手时我是否遗漏了什么?
  4. 是因为创建操作没有采取 build_category 方法,我需要将其添加到创建 行动?
  5. 将在 Category 模型 (presence: true) 上进行验证 在Post 表单上自动使用?

提前致谢。

更新:category_fieldsfields_for 块内丢失。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 form-for actioncontroller strong-parameters


    【解决方案1】:

    问题一:是的,你需要在post_params强参数方法中添加:category_attributes,如下所示:

    def post_params
      params.require(:post).permit(:body, category_attributes: [:title])
    end
    

    问题 #2: 是的,参数应该嵌套,这是您视图中的一个错字,因为您没有在父级范围内应用 fields_for(顺便说一句是复数)表单生成器,您也没有在fields_for 块内使用category_fields 表单生成器!

    视图应如下所示:

    <%= form_for @post do |form| %>
    
      <%= form.label :body %>
      <%= form.text_area :body %>
    
      <%= form.fields_for :category do |category_fields| %>
        <%= category_fields.label :title %>
        <%= category_fields.text_field :title %>
      <% end %>
    
      <%= form.button "Add Post" %>
    
    <% end %>
    

    问题#3:由于您的视图中的表单构建混乱,按钮参数可能位于错误的位置。

    问题#4:如果您接受嵌套属性,则无需在创建操作中构建子模型

    问题#5: 是的,子模型的验证也在运行,如果子模型的验证失败,父模型也会出错,不会保存到数据库中。

    【讨论】:

    • 雪橇,您先生是个绅士。感谢您指出我的错误方法。几天来我一直在看同一个表单,不知道我需要在 fields_for 块中添加 form.builder 。再次感谢您阐明强参数嵌套属性。我非常感谢您花时间回答我所有的问题。谢谢! :)
    【解决方案2】:

    @sled 你是对的。但是对于未来的 Rails 4.1,粗体 (**) 将被弃用

    def post_params
      params.require(:post).permit **(:body, :category_attributes => [:title])**
    end
    

    bolded 将被强制为 (:body, category_attributes: [:title])

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-19
      • 1970-01-01
      相关资源
      最近更新 更多