簡體   English   中英

僅允許針對特定參數進行一次更新?

[英]Allowing only one update for specific param?

如何填充參數,使其無法再次更新或編輯?

問題:我有一個參數:video,一旦填滿,它將向客戶收費。 我要使其填充后就無法再進行更新或編輯。

我已在視圖方面采取了預防措施,即一旦視頻上傳,編輯/更新表單將被隱藏並且無法再次創建,但是我注意到,如果由於某種原因更新失敗,可以將頁面返回到並且可以再次填寫更新表格(即使視頻已上傳),從而再次向客戶收取兩次費用。

工作原理:客戶創建訂單,創建數據條ID,一旦賣家履行了訂單(通過上傳文件或視頻),便收取了費用。

  def charge_update
    respond_to do |format|
      @amount = (@order.order_price).to_i * 100
      @amount_seller = (@order.order_price).to_i * 75
      if @order.update(order_charge)
        begin
                      charge = Stripe::Charge.create({
                        :amount      => (@order.order_price).to_i * 100,
                        :description => 'Rails Stripe customer',
                        :currency    => 'usd',
                        :customer => @order.stripe_customer_token,
                        :destination => {
                          :amount => @amount_seller ,
                          :account => (@order.seller.stripe_token),
                        }
                      })
                    rescue Stripe::CardError => e
                      charge_error = e.message
                    end
          @order.update_column(:order_status, 2)
          format.html { redirect_to ([@user, @order]), notice: 'Order was successfully uploaded.' }
          format.json { render :show, status: :ok, location: @order }
        elsif
          if charge_error
            flash[:error] = charge_error
            redirect_to user_order_path([@user, @order])
          else
          format.html { render :edit }
          format.json { render json: @order.errors, status: :unprocessable_entity }
        end
      end
    end
  end
private

def order_charge
      params.require(:order).permit(:video, :order_status)
    end

請隨時告訴我是否有更好的方法來驗證客戶的費用。 我最大的擔心是,由於賣方混亂,惡意等原因,客戶被多次收取費用。我想保證僅向客戶收取一次費用。 我能想到的唯一方法是只允許對視頻列進行一次更新。

要么為每個視頻表ID唯一的order_id的視頻創建一個單獨的表。

UPDATE

我最終做了下面的工作,...如果有任何更好的想法,我願意提出建議!

def charge_update
    respond_to do |format|
    if @order.video.present?
      format.html { redirect_to ([@user, @order]), notice: 'Order already completed!.' }
      format.json { render :show, status: :ok, location: @order }
    else
        @amount = (@order.order_price).to_i * 100
        @amount_seller = (@order.order_price).to_i * 75
        if @order.update(order_charge)
          begin
...
...
...
end

更好的方法是制作一個具有這些值的表

order_id 
video_id 
user_id 
charged (Boolean Value )

客戶下訂單並對其收費后,您可以填寫這些值並將收費值設為true。

您可以先檢查他是否已訂購該視頻,然后再重新付款。

這是您可以為此建立模型的示例

  class CustomerOrder < ActiveRecord::Base
  belongs_to :customer
  belongs_to :order
  belongs_to :video      
  end 

在客戶下新訂單之前,您可以檢查是否存在任何關系

   @customerorder =CustomerOrder.where(video_id: @video.id , user_id: @user.id , charged :true )

我將使用ActiveModel::Dirty實現回調,以在列值更改 為非 null或nil之外的任何值時啟動對任何更改的回滾。

class Amount < ActiveRecord::Base
  include ActiveModel::Dirty

  before_save :check_video

  attr_accessor :video # or whatever your video attribute is

  private

  def check_video
    false if video_changed? && !video_was.nil? # or empty or whatever
    true
  end
end

我將確保在模型層中,一旦成功創建記錄,就無法再對其進行更新。

一種簡單的方法可能是重寫readonly? Rails用於在內部檢查只讀記錄的方法:

# in your model
def readonly?
  super || video.present? && persisted?
end

在只讀實例上調用save將引發ActiveRecord::ReadOnlyRecord異常。

使用這種方法,您可以編寫if @order.readonly? 在控制器中,並查看@order是否仍可更新。

我最終創建了一個僅用於上傳視頻文件的控制器。

這樣,我可以在創建過程中使用費用代碼創建上傳文件,然后無需單獨進行更新就可以進行更新...

到目前為止,這是控制器的要點:

def create

    @video_order = VideoOrder.new(video_order_params)
    @order = Order.find(params[:order_id])

    @video_order.order_id = @order.id

    respond_to do |format|
      if @order.video_order.present?
          format.html { redirect_to @order, notice: 'Already complete dog!.' }
          format.json { render :show, status: :created, location: @video_order }
        else

      if @video_order.valid?
        begin
          charge = Stripe::Charge.create({
            :amount      => (@order.order_price).to_i * 100,
            :description => 'Rails Stripe customer',
            :currency    => 'usd',
            :customer => @order.stripe_customer_token,
            :destination => {
              :amount => @amount_seller ,
              :account => (@order.seller.stripe_token),
            }
          })
        rescue Stripe::CardError => e
          charge_error = e.message
        end
        if charge_error
          flash[:error] = charge_error
          redirect_to '/'
        else

          if @video_order.save
            @order.update_column(:order_status, 2)
            format.html { redirect_to @order, notice: 'Video order was successfully created.' }
            format.json { render :show, status: :created, location: @video_order }
          else
            format.html { render :new }
            format.json { render json: @video_order.errors, status: :unprocessable_entity }
          end
        end
      end
    end
  end
end

  # PATCH/PUT /video_orders/1
  # PATCH/PUT /video_orders/1.json
  def update
    respond_to do |format|
      if @video_order.update(video_order_params)
        format.html { redirect_to user_order_path([@user, @order]), notice: 'Video order was successfully updated.' }
        format.json { render :show, status: :ok, location: @video_order }
      else
        format.html { render :edit }
        format.json { render json: @video_order.errors, status: :unprocessable_entity }
      end
    end
  end

為了防止萬一,我在create方法中也有預防措施。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM