Search code examples
ruby-on-rails-5rails-admin

NoMethodError in RailsAdmin::MainController#edit


I have deposit and wallet models in my rails admin. I am using wallet in deposit model as:

wal=Wallet.where(user_id: self.user_id)
wal.balance = wal.balance + self.amount
wal.save!

Error:

NoMethodError in RailsAdmin::MainController#edit

The result of

puts wal.inspect

is

<ActiveRecord::Relation [#<Wallet id: 1, balance: 200, user_id: 22, created_at: "2019-03-20 04:57:45", updated_at: "2019-03-20 06:43:32">]>

I found the solution, but I don't think its a proper approach

wal=Wallet.where(user_id: self.user_id)
wal[0].balance = wal[0].balance + self.amount
wal[0].save!

Any help would be appreciated. Thanks in advance.


Solution

  • .where always returns a relation and not an object. The relation is basically an array of objects. Regardless if your search returns one,zero or many objects.

    So the clean way of doing this is similar to your approach. You just select the object in the index 0 position of the relation array.

    wal = Wallet.where(user_id: self.user_id).first
    

    Another approach could be that you add a relation to the user model. Assumption would be that you make sure User always has just exactly one wallet and you have the user available.

    # model
    has_one :wallet
    # controller
    user = User.find(self.user_id)
    wal = user.wallet
    

    Find always returns one object (if it exists) since there can only be one. Also an approach could be .find_by. Its similar to find but works for other object fields. For this you have to make sure that there is only one wallet per user since find_by returns just the first object even if there are multiple objects that match the query.

    Wallet.find_by(user_id: self.user_id)
    

    The last 2 examples have the advantage that they return a ActiveRecord::RecordNotFound when there is no match. The .where returns only an empty relation array.