I was reading an article and ran into the 1st example code. In the model the instance variable is set to avoid unnecessary queries. I also saw this in one of the railscasts (2nd example). On the other hand I read in more articles that if I use this pattern then my app may won't be thread safe so I can't take advantages of my puma webserver.
Could sby tell me when/where I should use this pattern?
1st example:
def first_order_date
if first_order
first_order.created_at.to_date
else
NullDate.new 'orders'
end
end
private
def first_order
@first_order ||= orders.ascend_by_created_at.first
end
2nd example
def shipping_price
if total_weight == 0
0.00
elsif total_weight <= 3
8.00
elsif total_weight <= 5
10.00
else
12.00
end
end
def total_weight
@total_weight ||= line_items.to_a.sum(&:weight)
end
UPDATED questions
1st example
As I see this 'first_order_date' is always called on an object (https://robots.thoughtbot.com/rails-refactoring-example-introduce-null-object), so I don't exactly see how the extra query can be avoided. I'm sure I'm wrong but according to my knowledge it could be just
def first_order_date
if orders.ascend_by_created_at.first
first_order.created_at.to_date
else
NullDate.new 'orders'
end
end
Or the may use the @first_order somewhere else as well?
2nd example
The code in the original question is not equivalent with this?
def shipping_price
total_weight = line_items.to_a.sum(&:weight)
if total_weight == 0
0.00
elsif total_weight <= 3
8.00
elsif total_weight <= 5
10.00
else
12.00
end
end
I see here what they achieve with defining total_weight, but why is it better to use an instance variable over my example?