如果你只是想設置一個實例變量沒有在初始化任何額外的邏輯則維傑的回答是一個很好的一個。但是,您可以擁有更多的靈活性,而不僅限於attr
方法。
與所有的紅寶石,你總是可以利用super
如果你保持正確的接口超級方法。 ActiveRecord::Base#initialize
只需要一個可選參數,即屬性和值的hash
。如果給出一個塊,它也會自動產生一個塊。 https://github.com/rails/rails/blob/master/activerecord/lib/active_record/core.rb#L313
所以,如果你想設置在初始化實例變量還沒有定義任何公共接入方式,您可以:
class Quote < ApplicationRecord
def initialize(attributes = nil, &block)
@my_var = attributes.delete(:my_var) if attributes
super
end
end
quote = Quote.new(my_var: 'value')
quote.instance_variable_get(:@my_var) # => "value"
您還可以執行更復雜的操作。假設你有User has_many :posts
和Post belongs_to :user
,User
有:name
和Post
有:title
。
class User < ApplicationRecord
def initialize(attributes = nil, &block)
title = attributes.delete(:first_post_title) if attributes
super
posts.build(title: "#{name}'s first post: #{title}") if title
end
end
user = User.new(first_post_title: 'Hello, world!', name: 'Matz')
user.posts.first # => #<Post:xxxxxxxxxxx title: "Matz's first post: Hello, world!">
希望這演示如何靈活的是,即使ActiveRecord
對象,有時可能回調是有點實施過於複雜和限制性在使用時如果使用得當super
可以工作得很好,甚至更好。
這兩個真正有用的答案,謝謝你們。希望我能接受兩個答案,但是因爲我不能,所以我不得不接受M.西蒙博格斯的解釋提供了很長的時間,儘管維傑是一個非常好的答案。再次感謝維傑,下次再見。 – jbk