Methods in Rails modules
Modules are commonly used to to group constants holding possible attribute values. Like in the example below we have a Order class and it has attribute status.
Status can hold different values as pending, confirmed, cancelled etc.
class Order < ApplicationRecord
module Status
PENDING = 'Pending'
CONFIRMED = 'Confirmed'
CANCELLED = 'Cancelled'
DECLINED = 'Declined'
COMPLETED = 'Completed'
end
validates_inclusion_of :status, in: [Status::PENDING, Status::CONFIRMED, Status::CANCELLED, Status::DECLINED, Status::COMPLETED]
end
When a new order is placed or existing order updated we want to ensure that status attribute contains valid value. We are using rails validation method validates_inclusion_of to achieve that. Since we are using all status values if we introduce a new status then we also need to change validation.
It can be avoided. Create a class all method inside module Status.
class Order < ApplicationRecord
module Status
PENDING = 'Pending'
CONFIRMED = 'Confirmed'
CANCELLED = 'Cancelled'
DECLINED = 'Declined'
COMPLETED = 'Completed'
def self.all
constants.map {|const| const_get(const)}
end
end
validates_inclusion_of :status, in: Status.all
end
You can add more methods which can be used in other places. Like in example below I have a method active? in order class. Order is considered as active when its pending or confirmed.
def active?
status.in?([Status::PENDING, Status::CONFIRMED])
end
Here as well we can add another class method active in status module and use it in active? method like below:
class Order < ApplicationRecord
module Status
PENDING = 'Pending'
CONFIRMED = 'Confirmed'
CANCELLED = 'Cancelled'
DECLINED = 'Declined'
COMPLETED = 'Completed'
def self.all
constants.map {|const| const_get(const)}
end
def self.active
[Status::PENDING, Status::CONFIRMED]
end
end
validates_inclusion_of :status, in: Status.all
def active?
status.in?(Status.active)
end
end
Hope this helps you in writing minimal code and avoids mistakes as well.
Happy coding!!!