Ami*_*tel 4 activerecord ruby-on-rails ruby-on-rails-3
我正在阅读Rails 3 Way的书,并感到困惑:
:after_add => callback 通过<<方法将记录添加到集合中后调用。不是由集合的create方法触发的
据我了解book.chapters.create(title:'第一章')不会调用before_add回调,但实际上是在调用。
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
Run Code Online (Sandbox Code Playgroud)
在控制台中(最小)
> 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
Run Code Online (Sandbox Code Playgroud)
在这里,您可以看到after_add为调用了回调create。
我误会了吗?
编辑
b.chapters.new(title: 'New Chapter')
b.chapters.build(title: 'New Chapter')
Run Code Online (Sandbox Code Playgroud)
也调用回调
将项目添加到集合时会触发before_add和after_add回调。与是否将记录保存到数据库无关。(对于has_and_belongs_to_many和has_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'
Run Code Online (Sandbox Code Playgroud)