Virtual Attributes in Ruby on Rails
Let’s play with getter and setter from Ruby
Let’s consider a case when you have a Product
model with attributes from migration such as name
, price
and quantity
. For some reason, you also need an additional title
attribute or you just need to modify the name
attribute and use it as title
for either in Product
form or just to display on the view page.
So let’s discuss what are the possible options to add such attributes to the model.
class Product def initialize(name, price, quantity)
@name = name
@price = price
@quantity = quantity
end # getter
def title
"Exlusive #{@name}"
end # setter
def title=(value)
@title = value
end
endproduct = Product.new('Cookies', 1, 10)
p product.name # => "Cookies"
p product.title # => "Exclusive Cookies" product.title='Summer Shirt'
p product.title # => "Summer Shirt"
In this way, we can get the title
value by the getter
method and also set the value by the setter
method without even adding any additional migration. Use cases could vary as per the requirement such as virtual attribute full_name
when migration attributes as first_name
and last_name
and many more.
Alternatively, we can perform the same operation using attr_accessor
, attr_reader
and attr_writer
. Ruby actually lets you create virtual attributes this way, which keeps you from having to manually create getter and setter methods as given below,
attr_reader :title # getter
attr_writer :title # setter
attr_accessor :title # both getter and setter
So if we stick to our previous example then it can be modified as,
class Product
attr_accessor :title def initialize(name, price, quantity)
@name = name
@price = price
@quantity = quantity
@title = "Exlusive #{@name}"
endendproduct = Product.new('Cookies', 1, 10)
p product.name # => "Cookies"
p product.title # => "Exclusive Cookies" product.title='Summer Shirt'
p product.title # => "Summer Shirt"
This is an example for attr_accesor
as it can be used as the getter
and as the setter
both. For some reason, if we just want to read(get) or just write(set) the attribute then we have the option to use attr_reader
or attr_writer
as well.