Rails 4 has_one关联形式没有建立

时间:2013-11-06 03:46:01

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

我需要一些关于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

在帖子#新动作中表单

<%= 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 %>

提交帖子表单时,它不会保存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. 我不确定是否必须在:category_attributes强参数方法中添加post_params
  2. 日志和调试参数是否应显示Category属性 嵌套在Post参数?
  3. Category哈希参数中,有一个空白button密钥不在我的fields_for我在使用表单助手时遗漏了什么?
  4. 原因是因为创建动作没有采取 build_category方法,我需要将其添加到创建中 动作?
  5. Category模型(presence: true)上的验证是否正确 自动在Post表单上使用?
  6. 提前致谢。

    更新:category_fields块内缺少fields_for

2 个答案:

答案 0 :(得分:15)

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

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

问题#2:是的,参数应该是嵌套的,这是您视图中的拼写错误,因为您没有在范围内应用fields_for(复数)父表单构建器,您还没有在category_fields块中使用fields_for表单构建器!

视图应如下所示:

<%= 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:是的,也会运行子模型的验证,如果子项验证失败,父项也会出错并且不会保存到数据库中。< / p>

答案 1 :(得分:2)

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

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

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