我在我的博客应用中使用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>
我的问题是:
nested_attributes
? before_save
关于如何对此进行编码的任何提示都将非常感激。
答案 0 :(得分:0)
name
不是帖子模型上的方法,而是第1类。由于尚未定义类别,因此您无法真正依赖于:self.category.name
。您需要以其他形式定义名称值。现在,如果您计划使用accepts_nested_attributes_for
,您应该能够完全放弃该方法,并且只需要数据哈希包含类别名称:
{ title: 'Post Title', category: { name: 'blog' } }
如果你没有走那条路,你应该设置一个传统的公共方法来通过将参数传递给这个方法来创建类别,而不是使用活动记录回调。此外,由于find_or_initialize()
将返回一个对象,因此使用谓词方法并没有多大意义。 generate_category?
应该成为generate_category