Reputation: 380
i have a class Equipment, which has a method do decide if the object is available or not. This method has some logic to check thought a has_many association, and returns true or false, so, it only work in instantiated object.
There is some way to do something like:
@someVar = Equipament.all.available
I solve this making:
equipament.rb
has_many :rents
def available
if(self.rents.blank?)
return true
else
if(self.rents.last.end.blank?)
return false
else
return true
end
end
end
def self.usable
ary = Array.new
Equipament.all.each do |eq|
if eq.available
ary.push(eq)
end
end
return ary
end
And then
@someVar = Equipament.usable
But, is this a nice way or there are something more efficient/elegant?
Upvotes: 2
Views: 1655
Reputation: 23671
This should do the trick
equipament.rb
has_many :rents
def available
(self.rents.blank? && !self.rents.last.end.blank?) ? true : false
end
def self.usable
ary = Array.new
Equipament.all.each do |eq|
if eq.available
ary.push(eq)
end
end
return ary
end
Upvotes: 0
Reputation: 306
Apart from the infinite database queries your code could be making, the whole approach is not flexible. There could be many other reasons why the Equipment
wouldn't be available
other than rents
. It could be in maintenance for example. That would mean making the available
method even more complicated. Therefore, I believe defining a state
for the Equipment
would be much easier to maintain. You would change the Equipment.state
based on certain events. In your case, you can change the Equipment.state
to rented
whenever someone rent it, and change it back to available
whenever it gets returned. Not only you could now cover many more cases, but you will be also able to get a list of all available equipment with a simple method which fires only one query to the database:
# models/equipament.rb
def self.available
where(state: :available)
end
Upvotes: 1