'undefined method `money' for #<ActiveRecord::Relation [#<Account id: nil, money: 400.0>]>
NoMethodError in AccountsController#update
undefined method `money' for #<ActiveRecord::Relation [#<Account id: nil, money: 400.0>]>
I'm tring to get a value from database and compare to another.
After compere I want to sum then update.
Ex: Value from money database is 4000 money_to_take is 1000
if money is >= money_to_take then money = money - money_to_take update the money value with 3000.
I do not know correctly where do I have to put this code.
Can some one help me how to solve this problem? Help me please!
model/account.rb
class Account < ApplicationRecord
belongs_to :user
enum status: {blocked: "blocked", activated: "activated"}
validates :number, presence: true, uniqueness: true
validates :money, presence: true, length: {minimum:1}
def self.update_withdraw_money(account_number, money_to_take)
account = select(:money).where(number:account_number)
if account.money >= money_to_take
@account.money -= money_to_take
end
end
end
This is the error line
if account.money >= money_to_take
Controllers/accounts_controller.rb
def withdraw
@account = Account.where(params[:number]).first
account = @account
account.money = 0.0;
@account_withdraw = account
logger.debug {"Last acount attributes hash: #{@account_withdraw.attributes.inspect}"}
end
def update
Account.update_withdraw_money(@account.number, @account.money)
respond_to do |format|
if @account.update(account_params)
format.html { redirect_to account_url(@account), notice: "Account was successfully updated." }
format.json { render :show, status: :ok, location: @account }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: @account.errors, status: :unprocessable_entity }
end
end
end
def account_params
params.require(:account).permit(:money, :status)
end
account table
class CreateAccounts < ActiveRecord::Migration[7.0]
def change
create_table :accounts do |t|
t.integer :number, default: 10000
t.float :money, default: 0.5
t.string :status, default: "activated"
t.references :user, null: false, foreign_key: true
t.timestamps
end
end
end
accounts/withdraw.html.erb
<h1>Withdraw from my account</h1>
<%= render "accounts/form", account: @account_withdraw%>
accounts/_form
<%= form_with(model: account) do |form| %>
<% if account.errors.any? %>
<div style="color: red">
<h2><%= pluralize(account.errors.count, "error") %> prohibited this account from being saved:</h2>
<ul>
<% account.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<div>
<%= form.label :money, style: "display: block" %>
<%= form.text_field :money %>
</div>
<div>
<%= form.hidden_field :status, value: "activated" %>
</div>
<div>
<%= form.submit %>
</div>
<% end %>
Use this address to access application http://127.0.0.1:3000/accounts/1000/withdraw .
Here is my code in github https://github.com/Vicente-jpro/negocial-app
Solution 1:[1]
Something like this
def self.update_withdraw_money(account_number, money_to_take)
account = find_by(number: account_number)
if account.money >= money_to_take
account.decrement!(:money, money_to_take)
end
end
After that you need @account.reload in the controller, because record is updated
And may be you need to wrap these updates into transaction
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | mechnicov |
