2012-09-20 85 views
3

我讀的Rails 3路書,並在該點糊塗了:的has_many和:after_add /:before_add =>回調<<和創建方法

:after_add =>回調 後,一個叫記錄通過< <方法添加到集合中。不會調用before_add回調,但實際上它在呼喚:不被收集的 創建方法

據我瞭解book.chapters.create(「第一章」稱號)觸發。

class Book < ActiveRecord::Base 
    attr_accessible :title 
    has_many :chapters, :before_add => :add_chapter 

    private 
    def add_chapter(chapter) 
     logger.error('chapter added to book') 
    end 
end 

class Chapter < ActiveRecord::Base 
    belongs_to :book 
    attr_accessible :title 
end 

在控制檯(過壓縮)

> b = Book.first 
    Book Load (0.1ms) SELECT "books".* FROM "books" LIMIT 1 
> b.chapters.create(title: 'Last Chapter') 
    begin transaction 
chapter added to book 
    INSERT INTO "chapters" .... 
    commit transaction 

在這裏你可以看到,after_add回調援引create

我誤解了一些東西?

編輯

b.chapters.new(title: 'New Chapter') 
b.chapters.build(title: 'New Chapter') 

還調用回調

+0

在聲明中你有after_add和代碼中你有before_add這是一個錯誤嗎? –

+0

問題是錯誤的還是你理解問題? –

+2

我在Rails指南中看不到這種行爲。自書寫完以後,這種行爲可能會發生變化。 –

回答

2

,當一個項目被添加到集合的before_addafter_add回調被觸發。它與記錄是否保存到數據庫無關。 (這裏稍微有一個例外是has_and_belongs_to_manyhas_many :through關係,將它添加到集合中會立即通過ActiveRecord在內部反映到數據庫中)。

只要向集合添加新記錄,回調就會觸發。 before_add將在元素添加到集合之前調用,after_add之後調用。

下面的這個例子可能會給你一個更好的理解。

# id: integer 
class Author < ActiveRecord::Base 
    has_many :books, before_add: :bef, after_add: aft 

    def bef 
    puts "Before adding, author ##{id} has #{books.size} books" 
    end 

    def aft 
    puts "After adding, author ##{id} has #{books.size} books" 
    end 
end 

# id integer 
# author_id: integer 
class Book < ActiveRecord::Base 
    belongs_to :author 
    after_save: :saved 

    def saved 
    puts "The book is now saved!" 
    end 
end 

> book = Book.new 

> author = Author.first 

> author.books << book 
'Before adding, author #1 has 3 books' 
'After adding, author #1 has 4 books' 

> author.save 
'The book is now saved' 
+1

這使得該功能相當不值錢。當直接使用外鍵添加記錄時,回調不會被觸發。 – maletor

相關問題