attr_accessor default values
Rails has attr_accessor_with_default so you could write
class Like
attr_accessor_with_default :politics,false
end
i = Like.new
i.politics #=> false
and thats all
UPDATE
attr_accessor_with_default has been deprecated in Rails 3.2.. you could do this instead with pure Ruby
class Like
attr_writer :politics
def politics
@politics || false
end
end
i = Like.new
i.politics #=> false
How to do attr_accessor_with_default in ruby?
attr_accessor :pancakes
def after_initialize
return unless new_record?
self.pancakes = 11
end
This ensures that the value is initialized to some default for new record only.
best way to set a default value on a property without ActiveRecord?
class Foo
# class-level instance variable
# setting initial value (optional)
@class_var = 42
# making getter/setter methods on the class itself
class << self
attr_accessor :class_var
end
# instance-level variable getter/setter methods
attr_accessor :inst_var
def initialize
# setting initial value (optional)
@inst_var = 17
end
end
p Foo.class_var
#=> 42
Foo.class_var = 99
p Foo.class_var
#=> 99
f1 = Foo.new
f2 = Foo.new
f2.inst_var = 1
p [f1.inst_var, f2.inst_var]
#=> [17,1]
How to initialize 'attr_accessor' attribute values?
For Rails 3.2 or earlier, you could use attr_accessor_with_default
:
class User < ActiveRecord::Base
attr_accessor_with_default :attribute_name1, true
attr_accessor_with_default :attribute_name2, true
attr_accessor_with_default :attribute_name3, true
...
end
Since your default value is an immutable type (boolean), this form of the method is safe to use here. But don't use it if the default value is a mutable object, including an array or string, because all of your new model objects will share the exact same instance, which is probably not what you want.
Instead, attr_accessor_with_default
will accept a block, where you can return a new instance each time:
attr_accessor_with_default(:attribute_name) { FizzBuzz.new }
Regarding attr_accessor and def initialize
attr_accessor is just an attribute and by default it is nil. You cannot assign any value to it. If you need it to an array then initialize it as an array before using it.
Intermingling attr_accessor and an initialize method in one class
initialize
and attr_accessor
have nothing to do with each other. attr_accessor :name
creates a couple of methods:
def name
@name
end
def name=(val)
@name = val
end
If you want to set name upon object creation, you can do it in the initializer:
def initialize(name)
@name = name
# or
# self.name = name
end
But you don't have to do that. You can set name later, after creation.
p = Person.new
p.name = "David"
puts p.name # >> "David"
What is attr_accessor in Ruby?
Let's say you have a class Person
.
class Person
end
person = Person.new
person.name # => no method error
Obviously we never defined method name
. Let's do that.
class Person
def name
@name # simply returning an instance variable @name
end
end
person = Person.new
person.name # => nil
person.name = "Dennis" # => no method error
Aha, we can read the name, but that doesn't mean we can assign the name. Those are two different methods. The former is called reader and latter is called writer. We didn't create the writer yet so let's do that.
class Person
def name
@name
end
def name=(str)
@name = str
end
end
person = Person.new
person.name = 'Dennis'
person.name # => "Dennis"
Awesome. Now we can write and read instance variable @name
using reader and writer methods. Except, this is done so frequently, why waste time writing these methods every time? We can do it easier.
class Person
attr_reader :name
attr_writer :name
end
Even this can get repetitive. When you want both reader and writer just use accessor!
class Person
attr_accessor :name
end
person = Person.new
person.name = "Dennis"
person.name # => "Dennis"
Works the same way! And guess what: the instance variable @name
in our person object will be set just like when we did it manually, so you can use it in other methods.
class Person
attr_accessor :name
def greeting
"Hello #{@name}"
end
end
person = Person.new
person.name = "Dennis"
person.greeting # => "Hello Dennis"
That's it. In order to understand how attr_reader
, attr_writer
, and attr_accessor
methods actually generate methods for you, read other answers, books, ruby docs.
Specify default values for instance variables outside constructor
One thing you can do is call a method from the initialize
of Animal
, providing a hook for subclasses to add custom functionality:
class Animal
attr_reader :age
def initialize(age)
@age = age
setup_defaults
end
private
def setup_defaults
# NOOP by default
end
end
class Sheep < Animal
attr_accessor :likes
private
def setup_defaults
@likes = []
end
end
A second way, that you mention in your post, you can do this is use a custom def likes
instead of the attr_reader
/attr_accessor
:
def likes
@likes ||= [] # shorter way of doing what you have
end
As a third option, if you don't mind using initialize
(your primary concern seems to be possibly changing the superclass' signature), since you don't care about any the parameters to initializeSheep
is you can overwrite the initialize
like:
class Sheep < Animal
attr_accessor :likes
def initialize(*)
super
@likes = []
end
end
this is the same as doing something like def initialize(*args)
except you don't name the variable, and works since super
passes in the original arguments by default. Now, if you go back and change animal to have, say, a name
argument to its initialize
:
class Animal
attr_reader :age, :name
def initialize(name, age)
@name = name
@age = age
end
end
Sheep
still works without any changes.
Related Topics
In Ruby, How to I Control the Order in Which Test::Unit Tests Are Run
What Is a Robust Installation Process for Nokogiri (On Ubuntu)
Can't Run Jenkins Build - Bundle: "Command Not Found"
What Is the Activemodel Method Attribute "_Was" Used For
How to Assign Multiple Values to a Hash Key
Convert Ruby to Low Level Languages
Cannot Load Such File -- 1.9/Bcrypt_Ext (Loaderror)
Ruby Bundle Install Require: No Such Files to Load Error
Sinatra with a Persistent Variable
Run Rails Commands Outside of Console
Define_Method: How to Dynamically Create Methods with Arguments
How to Find a Devise User by It's Session Id
Are Ruby 1.9 Regular Expressions Equally Powerful to a Context Free Grammar
Executing Shell Command in Background from Ruby with Proper Argument Escaping