Reputation: 2128
I have a function that uses first_or_create
on a record, and I need to be able to use +
on one of its attributes in the event that it exists.
Blob.where(user_id: user.id, item_id: item.id).first_or_create do |s|
s.amount += amount
end
However, I cannot use +
if the record does not exist. Is this a syntax issue or is it my use of first_or_create
?
Upvotes: 1
Views: 280
Reputation: 2950
The block is only called when a new object is created (one has not been found). If the model doesn't have a default value for the given field, it will try to call +
on a nil
value. You can do something along these lines (there might be a nicer way):
blob = Blob.where(user_id: user.id, item_id: item.id).first_or_create
blob.amount += amount if blob.amount.present?
In this situation, you only perform the sum
if the object already exists (which seems to be your goal according to your description). If you want to apply the amount sum in any situation, you can initialize the amount to 0
if the record does not yet exist:
blob = Blob.where(user_id: user.id, item_id: item.id).first_or_create do |b|
b.amount = 0
end
blob.amount += amount
In the example above, if a object exists then it will add amount
to the current value, otherwise it will initialize the attribute with 0
and then add amount
to it.
Upvotes: 5
Reputation: 7130
Perform a null check on s.amount. If it doesn't exist prior, s.amount
will be nil
, which naturally can't be added to.
You can do this by using the following.
Blob.where(user_id: user.id, item_id: item.id).first_or_create do |s|
if s.amount.nil?
s.amount = amount
else
s.amount += amount
end
end
Alternatively, you could probably set a default
of 0 on the field, though I'm not positive on that one.
Upvotes: 1