在Rails上使用find_or_initialize 5

时间:2016-07-25 14:00:28

标签: ruby-on-rails activerecord nested-attributes form-for ruby-on-rails-5

我在我的博客应用中使用Rails 5 find_or_initialize,其中帖子和类别已输入到输入文本字段中。

发布模型

# == Schema Information
#
# Table name: posts
#
#  id           :integer          not null, primary key
#  title        :string           default(""), not null
#  body         :text             default(""), not null
#  created_at   :datetime         not null
#  updated_at   :datetime         not null
#  category_id  :integer


class Post < ApplicationRecord
  validates :title, :body, :category, presence: true

  has_one :category
  accepts_nested_attributes_for :category
end

类别模型

# == Schema Information
#
# Table name: category
#
#  id         :integer          not null, primary key
#  name       :string           default(""), not null
#  created_at :datetime         not null
#  updated_at :datetime         not null

class Category < ApplicationRecord
  validates :name, presence: true
  validates :name, length: { in: 3..80 }

  has_many :posts
end

在控制台中,我可以使用以下方法:

post = Post.new(title: "Hello Stack Overflow", body: "How are you today?")
post.category = Category.find_or_initialize_by(name: "Greetings")
post.save

post.last
=> #<Post:0x007fd34fa21a23
 id: 42,
 title: "Hello Stack Overflow",
 body: "How are you today?",
 created_at: Mon, 25 Jul 2016 12:56:39 UTC +00:00,
 updated_at: Mon, 25 Jul 2016 12:56:39 UTC +00:00,
 category_id: 3>

邮政表格如下:

<%= form_for @post do |f| %>
  <fieldset>
    <%= f.label "Title" %>
    <%= f.text_field :body %>
  </fieldset>

  <fieldset>
    <%= f.fields_for :category do |category_fields|
       <%= f.label "Category" %>
       <%= category_fields.text_field :name %>
    <% end %>
  </fieldset>   
<% end %>

我的麻烦是尝试将类别fields_for中输入的内容输入Post模型以使用find_or_initialize

我尝试了以下内容:

class Post < ApplicationRecord
  before_save :generate_category?

  has_one :category
  accepts_nested_attributes_for :category

  private

   def generate_category?
     self.category = Category.find_or_initialize_by(name: name)
   end
end

此操作失败,我收到NameError错误:

NameError in PostController#create
undefined local variable or method `name' for #<Listing:0x007fc3d9b48a48>

我的问题是:

  1. 如何访问类别属性 - 有没有办法访问模型中的nested_attributes
  2. 我是否使用before_save
  3. 进行了正确的回调
  4. 我应该以某种方式在控制器中处理这个吗?
  5. 关于如何对此进行编码的任何提示都将非常感激。

1 个答案:

答案 0 :(得分:0)

name不是帖子模型上的方法,而是第1类。由于尚未定义类别,因此您无法真正依赖于:self.category.name。您需要以其他形式定义名称值。现在,如果您计划使用accepts_nested_attributes_for,您应该能够完全放弃该方法,并且只需要数据哈希包含类别名称:

{ title: 'Post Title', category: { name: 'blog' } }

如果你没有走那条路,你应该设置一个传统的公共方法来通过将参数传递给这个方法来创建类别,而不是使用活动记录回调。此外,由于find_or_initialize()将返回一个对象,因此使用谓词方法并没有多大意义。 generate_category?应该成为generate_category