2012-05-11 45 views
1

每個職位只有一個類別,我需要像訪問類別的名稱Rails數據庫關係:Post.category.name =? (未定義的方法'名稱')

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 
+0

我假設有一個數據庫字段名稱爲'類別'? – pduersteler

+0

@pdsuersteler:是的 – sparkle

+0

啊..傻的我... – pduersteler

回答

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;博士:

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

的問題是,你需要/想明確地建立分類記錄,如果它不存在。

爲了解決這個問題,我想在帖子創建category_name=方法:

一個category_name= settor也將採取"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文檔中的「關聯擴展」,以獲取另一種方法。

+0

Rails沒有一個本地方法來做到這一點? – sparkle

+0

是的,它定義了':belongs_to:category',因此你得到了setter和getters。 '.build'不自動保存,它只是將類別分配給'Post'集合。 – pduersteler

+0

但是最初的零案例不在默認的設置器中。這是整個問題! –

相關問題