Si vous voulez juste définir une variable d'instance sans aucune logique supplémentaire à l'initialisation, alors la réponse de Vijay est bonne. Cependant, vous pouvez avoir plus de flexibilité que d'être limité aux méthodes attr
.
Comme avec tout Ruby, vous pouvez toujours profiter de super
si vous maintenez la bonne interface à la super méthode. ActiveRecord::Base#initialize
ne prend qu'un argument optionnel, un hash
d'attributs et de valeurs. Il se rend également à un bloc si un bloc est donné. https://github.com/rails/rails/blob/master/activerecord/lib/active_record/core.rb#L313
Donc, si vous voulez définir une variable d'instance à l'initialisation sans définir également des méthodes d'accès public, vous pouvez:
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"
Vous pouvez également effectuer des opérations plus complexes. Supposons que vous avez User has_many :posts
et Post belongs_to :user
, User
a un :name
et Post
a un :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!">
Espérons que montre comment flexible, vous pouvez être même avec ActiveRecord
objets, et parfois callbacks sont un peu trop compliqué la mise en œuvre et restrictive en cours d'utilisation lorsque super
peut fonctionner très bien et encore mieux quand il est utilisé de façon appropriée.
Les deux réponses vraiment utiles, merci les gars. Je voudrais pouvoir accepter deux réponses, mais comme je ne peux pas je me suis senti obligé d'accepter M.Simon Borgs en raison de la longueur de l'explication fournie, bien que Vijay est une réponse parfaitement bonne aussi. Merci encore, Vijay, d'arriver la prochaine fois. – jbk