在 Rails 上使用 find_or_initialize 5

问题描述 投票:0回答:1

我正在我的博客应用程序中使用 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>

Post 表单如下所示:

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

我的麻烦是试图获取类别字段中输入的内容_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. 我应该以某种方式在控制器中处理这个吗?

任何关于我如何编写代码的提示都将不胜感激。

ruby-on-rails activerecord nested-attributes form-for ruby-on-rails-5
1个回答
0
投票

name
不是后模型上的方法,而是类别一上的方法。由于尚未定义类别,因此您也不能真正依赖调用:
self.category.name
。您需要以其他形式定义名称值。现在,如果您打算使用
accepts_nested_attributes_for
,您应该能够完全放弃该方法,而只需让数据的哈希值包含类别名称:

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

如果你不走那条路,你应该设置一个传统的公共方法来通过将参数传递给这个方法来创建类别,而不是使用活动记录回调。此外,由于

find_or_initialize()
将返回一个对象,因此使用谓词方法没有多大意义。
generate_category?
应该变成
generate_category

© www.soinside.com 2019 - 2024. All rights reserved.