Rails db关系:Post.category.name =? (未定义的方法`name')

时间:2012-05-11 21:15:13

标签: ruby-on-rails ruby ruby-on-rails-3 activerecord

每个帖子只有一个类别,我需要通过类似

的方式访问类别的名称
p = Post.new
p.category.name = "tech"
p.save

怎么做?


   class Category < ActiveRecord::Base
       has_many :posts, :dependent => :destroy

       attr_accessible :name, :image

    end

Post.rb

class Post < ActiveRecord::Base
    belongs_to :category

    attr_accessible :category_id, :name, :text, :lang, :image

end

Schema.rb

create_table "categories", :force => true do |t|
    t.string "name"
    t.string "image"
  end

2 个答案:

答案 0 :(得分:4)

您的示例包含问题。

p = Post.new
p.category.name = "tech"
p.save

首先,您创建一个新帖子。其次,您想为帖子的类别指定名称,但没有分配类别。这导致像post.nil.name这样的调用,其中nil将是类别对象,如果已分配,则不是这种情况。由于nil没有方法name,因此您会收到所描述的错误undefined method name for nil class

要解决此问题,首先需要指定一个类别来处理。

p.category = Category.firstp.category_id = 1。之后,p.category将返回类别对象,因此p.category.name有效,因为它在类别对象上调用而不在nil上。

<强> TL; DR:

p = Post.new
p.category # => nil
p.category.name # throws an error

p.category = Category.first
p.category # => <#Category ...>
p.category.name # => 'actual name of category'
p.category.name = 'foo' # works now

答案 1 :(得分:1)

问题是如果不存在,您需要/想要显式构建类别记录。

要解决这个问题,我想考虑在Post中创建一个category_name=方法:

category_name=设置员还会处理"law of Demeter"问题

class Post < ActiveRecord::Base
  belongs_to :category

  attr_accessible :category_id, :name, :text, :lang, :image

  attr_accessible :category_name=, :category_name

  def category_name=(name)
    self.category = Category.find_or_create_by_name(name)
  end

  def category_name
    category && category.name
  end

另请参阅ActiveRecord文档中的“关联扩展”,了解其他方法。