如何在用户进行交易时更新用户余额?

时间:2017-11-12 19:41:36

标签: ruby-on-rails ruby transactions marketplace balance

我试图编写代码,使用户可以在每次进行交易时更新余额。

这是一个简单的易货申请: 用户可以提供待售产品或从其他用户购买产品。 用户使用一种虚拟货币(单位)付款。 当用户点击订单时,执行交易。

模型包括:用户,产品和订单。

如果用户订购产品(此处为订单=交易),我预计订单价格(此处价格=金额)将添加到用户余额中:

我的期望是,order_controller中的这段代码可以使@price的数量通过并添加到@balance并使更新成为可能:



@user.balance = balance: (@user.balance += @order.price) 




但这不起作用

我在orders_controller中尝试过这个:



def balance
    if @order.save
@user.balance_update!(balance: @user.balance + @order.price)
end
end




但不起作用。

这段代码有什么问题? 请帮忙!

这些是相关文件:



class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable

validates :fullname,presence: true
validates :description, presence: false
validates :balance, presence: true, numericality:true

before_validation :load_defaults

def load_defaults
if self.new_record?
self.balance = 100
end
end
has_many :products
has_many :orders
end
&#13;
&#13;
&#13;

&#13;
&#13;
class Order < ActiveRecord::Base
belongs_to :user
belongs_to :product


validates :price, presence: true
validates :product_id, presence: true
validates :user, presence: true
end
&#13;
&#13;
&#13;

&#13;
&#13;
class Product < ActiveRecord::Base
belongs_to :user
has_many :orders
end
&#13;
&#13;
&#13;

&#13;
&#13;
class OrdersController < ApplicationController

before_action :authenticate_user!

def create
@order = current_user.orders.create(order_params)
@user.balance = balance: (@user.balance += @order.price)

redirect_to user_orders_path
end
end

def user_orders
@orders = current_user.orders
end

private
def order_params
params.require(:order).permit(:price, :user_id)
end
end
&#13;
&#13;
&#13;

&#13;
&#13;
class UsersController < ApplicationController

def show
@user = User.find(params[:id])
@products = @user.products
end
end
&#13;
&#13;
&#13;

&#13;
&#13;
class ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:show]
def index
@products = current_user.products
end

def show
end

def new
@product = current_user.products.build
end
def edit
end

def create
@product = current_user.products.build(product_params)

respond_to do |format|
if @product.save
format.html { redirect_to @product, notice: 'Product was successfully created.' }
format.json { render :show, status: :created, location: @product }
else
format.html { render :new }
format.json { render json: @product.errors, status: :unprocessable_entity }
end
end
end

def update
respond_to do |format|
if @product.update(product_params)
format.html { redirect_to @product, notice: 'Product was successfully updated.' }
format.json { render :show, status: :ok, location: @product }
else
format.html { render :edit }
format.json { render json: @product.errors, status: :unprocessable_entity }
end
end
end

def destroy
@product.destroy
respond_to do |format|
format.html { redirect_to products_url, notice: 'Product was successfully destroyed.' }
format.json { head :no_content }
end
end

private
def set_product
@product = Product.find(params[:id])
end

def product_params
params.require(:product).permit(:name, :description, :price)
end
end
&#13;
&#13;
&#13;

&#13;
&#13;
<p>
User name: <%= @user.fullname %>
</p>
<p>
Balance: <%= @user.balance %>
</p>
&#13;
&#13;
&#13;

&#13;
&#13;
ActiveRecord::Schema.define(version: 20171031150052) do
create_table "orders", force: :cascade do |t|
t.integer "user_id"
t.integer "product_id"
t.integer "price"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "transactiontype"
t.integer "buyer_id"
t.integer "seller_id"
end
add_index "orders", ["product_id"], name: "index_orders_on_product_id"
add_index "orders", ["user_id"], name: "index_orders_on_user_id"

create_table "products", force: :cascade do |t|
t.string "name"
t.text "description"
t.integer "price"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
end
add_index "products", ["user_id"], name: "index_products_on_user_id"

create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "fullname"
t.string "description"
t.integer "balance"
end
add_index "users", ["email"], name: "index_users_on_email", unique: true
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
&#13;
&#13;
&#13;

&#13;
&#13;
Rails.application.routes.draw do
  devise_for :users

 get 'pages/index'

  resources :products
  resources :users

  resources :products do
  resources :orders, only: [:create]
  end
 
 resources :orders, only: [:show]
get '/user_orders' => 'orders#user_orders'
end
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:0)

尝试 @user.update(balance: @user.balance + @order.price)

答案 1 :(得分:0)

如果您直接指定属性,则只需指定一个值,然后自己需要致电save

@user.balance = @order.price
@user.save!

或者您可以使用update(没有balance_update),然后使用哈希调用它:

@user.update!(balance: @user.balance + @order.price)