我的交易模型根据数量(整数列)生成一系列唯一的票号,并带有以下控制器逻辑:
@transaction.quantity.times.uniq { @transaction.ticket_numbers << rand(100000..999999) }
但是,这只能确保数组中的数字是唯一的。
我需要一个数据库验证来检查所有Transaction.ticket_numbers数组,以确保每个值(票号)在所有数组中都是唯一的。
这是schema.rb中的Transaction表:
create_table "transactions", force: :cascade do |t|
t.string "payee"
t.integer "quantity"
t.decimal "debt", precision: 8, scale: 2
t.string "email"
t.string "ministry"
t.integer "status"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "ticket_numbers", default: [], array: true
end
来自transaction.rb的交易模型:
require 'csv'
class Transaction < ApplicationRecord
belongs_to :user
validates :email, :format => { :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/, :on => [:create, :update] }
validates :payee, presence: true
validates :quantity, numericality: { greater_than_or_equal_to: 1 }
validates :debt, numericality: { greater_than_or_equal_to: 0 }
def self.to_csv
attributes = %w{payee email ministry quantity debt status ticket_numbers}
CSV.generate(headers: true) do |csv|
csv << attributes
all.each do |transaction|
csv << attributes.map{ |attr| transaction.send(attr) }
end
end
end
end
交易控制器:
class TransactionsController < ApplicationController
before_action :load_transaction, only: [:edit, :update, :destroy]
def create
@transaction = Transaction.new(transaction_params)
if @transaction.save
@transaction.quantity.times.uniq { @transaction.ticket_numbers << rand(100000..999999) }
end
@user = @transaction.user
@transactions = @user.transactions
respond_to do |format|
if @transaction.save && @transaction.status == 1
UserMailer.payment_confirmation(@transaction).deliver_later
format.html { redirect_to user_url(@user), notice:'Transaction added & ticket sent' }
format.json { render json: @user, status: :created, location: @user }
elsif @transaction.save && @transaction.status != 1
format.html { redirect_to user_url(@user), notice:'Transaction added' }
format.json { render json: @user, status: :created, location: @user }
else
format.html { render 'users/show' }
format.json { render json: @transaction.errors, status: :unprocessable_entity }
end
end
end
def edit
@user = current_user
end
def update
update_ticket_numbers
respond_to do |format|
if @transaction.update_attributes(transaction_params) && @transaction.status == 1
UserMailer.payment_confirmation(@transaction).deliver_later
format.html { redirect_to user_url(current_user), notice: 'Transaction info updated & confirmation email sent to payee' }
format.json { render json: current_user, status: :created, location: current_user }
elsif @transaction.update_attributes(transaction_params) && @transaction.status != 1
format.html { redirect_to user_url(current_user), notice: 'Transaction info updated' }
format.json { render json: current_user, status: :created, location: current_user }
else
format.html { render :edit }
format.json { render json: @transaction.errors, status: :unprocessable_entity }
end
end
end
def destroy
@transaction.destroy
redirect_to user_url(current_user), notice: 'Transaction deleted'
end
private
def load_transaction
@transaction = Transaction.find(params[:id])
end
def transaction_params
params.require(:transaction).permit(:payee, :email, :ministry, :debt,
:quantity, :status, :user_id, :ticket_numbers)
end
def update_ticket_numbers
if @transaction.update_attributes(transaction_params)
if @transaction.ticket_numbers.length < @transaction.quantity
i = @transaction.quantity - @transaction.ticket_numbers.length
i.times.uniq { @transaction.ticket_numbers << rand(100000..999999) }
elsif @transaction.ticket_numbers.length > @transaction.quantity
i = @transaction.ticket_numbers.length - @transaction.quantity
i.times { @transaction.ticket_numbers.pop }
end
end
end
端
答案 0 :(得分:0)
您可以向模型添加自定义票证编号验证。您可以了解有关它们的更多信息here
class Transaction < ApplicationRecord
validate :ticket_number_uniqueness
def ticket_number_uniqueness
# First check all new ticket numbers are unique from each other
errors.add(:ticket_number, "is not unique") unless ticket_numbers == ticket_numbers.uniq
# Next check against other ticket numbers
ticket_numbers.each do |ticket|
if ::Transaction.where("ticket_numbers @> '{?}'", ticket).exists?
errors.add(:ticket_number, "is not unique")
end
end
end
end
注意:这是利用Postgres包含数组方法@>的优势。您可以了解有关数组方法here
的更多信息