我有一个基于作用域的唯一性验证:validates :company_standard, uniqueness: { scope: :company_id }
on a Rails Model X
.
在所附的屏幕截图中,我试图通过表单(=标准流程)为该公司创建一个X
类的新对象,没有激活company_standard
字段或任何其他布尔字段。
但是,保存失败,在company_standard
上出现uniqueness
验证错误(参见屏幕截图)。
这个公司的类X
的一个单独的对象存在于数据库中,其company_standard=true(我仔细检查了表单是否命名正确)。更新现有记录并将boolean字段设置为false似乎也会失败,并出现相同的验证错误。
不知道为什么会失败。在我看来是意料之外的行为。
@mechnicov评论后更新:型号
class MeanOfPayment < ApplicationRecord
belongs_to :company
has_many :in_payments
has_many :out_payments
has_many :bank_statements, dependent: :destroy
validates :company_standard, uniqueness: { scope: :company_id }
before_validation :remove_spaces
def balance
...
end
def account_name
...
end
private
def remove_spaces
...
end
end
控制器
class Home::MeanOfPaymentsController < HomeController
def index
@title = t('titles.mean_of_payments.index')
@mean_of_payments = current_company.mean_of_payments
end
def show
@title = t('titles.mean_of_payments.show')
@mean_of_payment = current_company.mean_of_payments.find(params[:id])
end
def new
@title = t('titles.mean_of_payments.new')
company_id = Company.find(params[:company_id]).id
@mean_of_payment = MeanOfPayment.new(company_id: company_id)
end
def create
fix_number(mean_of_payment_params[:balance_at_date])
@mean_of_payment = (mean_of_payment_params[:type].constantize).new(mean_of_payment_params)
if @mean_of_payment.save
redirect_to home_company_mean_of_payments_path(Company.find(params[:company_id])), notice: t('mean_of_payment.notifications.create_successfully')
else
render :new
end
end
def edit
@title = t('titles.mean_of_payments.edit')
@mean_of_payment = MeanOfPayment.find(params[:id])
end
def update
fix_number(mean_of_payment_params[:balance_at_date])
@mean_of_payment = MeanOfPayment.find(params[:id])
if @mean_of_payment.update(mean_of_payment_params)
redirect_to home_company_mean_of_payments_path(Company.find(params[:company_id])), notice: t('mean_of_payment.notifications.update_successfully')
else
render :edit
end
end
def destroy
mean_of_payment = MeanOfPayment.find(params[:id])
company_id = mean_of_payment.company.id
mean_of_payment.update!(marked_deleted: true)
redirect_to home_company_mean_of_payments_path(company_id: company_id), method: :destroy, notice: t('mean_of_payment.notifications.delete_successfully')
end
private
def mean_of_payment_params
validation = if params[:bank_account].present?
params.require(:bank_account)
elsif params[:cash_counter].present?
params.require(:cash_counter)
elsif params[:mean_of_payment].present?
params.require(:mean_of_payment)
else
raise "Zahlungsmethode muss im Controller eingeführt werden!"
end
validation.permit(
:account_name,
:account_number,
:balance_at_date,
:balance_date,
:bank_name,
:bank_number,
:company_id,
:company_standard,
:for_out_invoice,
:owner,
:primary_debitable,
:type,
)
end
end
查看1 -新增
<div class="row">
<div class="col-8 offset-2">
<%= link_to t('common.buttons.back'), home_company_mean_of_payments_path %>
<h1>
<%= t('mean_of_payment.new.title') %>
</h1>
<%= render 'form', path: home_company_mean_of_payments_path(id: current_company.id) %>
</div>
</div>
查看2 -表单
<%= simple_form_for @mean_of_payment, url: path do |f| %>
<%= f.hidden_field :company_id, value: current_user.accounting_company.id %>
<div class="row">
<div class="col-6">
<div class="ibox float-e-margins">
<div class="ibox-content">
<% if @mean_of_payment.errors.any? %>
<div id="error_explanation">
<h4><%= t('activerecord.errors.models.mean_of_payment.prohibited_save', count: @mean_of_payment.errors.count) %></h4>
<ul>
<% @mean_of_payment.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="form-group">
<%= f.label :type %>
<%= f.select :type, options_for_mean_of_payment_general, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :bank_name %>
<%= f.text_field :bank_name, class: 'form-control w-50' %>
</div>
<div class="form-group">
<%= f.label :bank_number %>
<%= f.text_field :bank_number, class: 'form-control w-50' %>
</div>
<div class="form-group">
<%= f.label :account_name %>
<%= f.text_field :account_name, class: 'form-control w-50'%>
</div>
<div class="form-group">
<%= f.label :account_number %>
<%= f.text_field :account_number, class: 'form-control w-50' %>
</div>
<div class="form-group">
<%= f.label :owner %>
<%= f.text_field :owner, class: 'form-control w-50' %>
</div>
<div class="form-group">
<%= f.label :balance_at_date %>
<%= f.text_field :balance_at_date, class: 'form-control w-50' %>
</div>
<div class="form-group">
<%= f.label :balance_date %>
<%= f.input :balance_date, as: :date, html5: true, class: 'form-control w-50', label: false %>
</div>
<div class="form-group">
<%= f.label :company_standard %>
<%= f.check_box :company_standard, class: 'form-control w-50' %>
</div>
<div class="form-group">
<%= f.label :for_out_invoice %>
<%= f.check_box :for_out_invoice, class: 'form-control w-50' %>
</div>
<div class="form-group">
<%= f.label :primary_debitable %>
<%= f.check_box :primary_debitable, class: 'form-control w-50' %>
</div>
<div class="form-group">
<%= f.submit t('common.buttons.create_or_modify'), class: 'btn btn-primary' %>
</div>
</div>
</div>
</div>
</div>
<% end %>
3条答案
按热度按时间ttcibm8c1#
更新现有记录并将boolean字段设置为false似乎也会失败,并出现相同的验证错误。
这强烈暗示您的数据库包含另一条带有
company_standard=false
的company_id
记录。请从rails控制台检查这一点,如下所示:请通过复制/粘贴这些控制台命令和对问题的回答来显示这一点。如果只有一个记录,那么下一个明显的嫌疑人是你的
remove_spaces
调用,请将代码添加到你的问题中。esbemjvw2#
您正在从
params[:company_id]
设置company_id
只是为了在你的表单中覆盖它
不管参数是多少,我假设它都是一样的。
你的URL也有点可疑:
这就是
params[:id]
。这不是意味着该控制器的mean_of_payment.id
吗?home_company_mean_of_payments
-复数,所以id
似乎不合适,你正在创建你还没有一个id。查看您的日志,看看您提交的参数。很难分辨你期望的company_id和提交的company_id:
anauzrmj3#
看来我对
uniquness
验证器的理解是错误的(花了2天时间才发现...)。WRONG我认为它可以确保一个属性只被设置为true一次(即我的想法:'非常地')。
CORRECT但它实际上检查属性是否存在。所以
false
也存在于这种情况下,即not nil
(如果Rails代码检查nil,则没有仔细检查)。现在看起来很傻:)。所以我的情况
一个
company has_many mean_of_payments
,但只有一个布尔属性company_standard
是true
。当然,uniform验证不起作用,因为其他
mean_of_payments
将company_standard
设置为false
。我需要一个验证器,它检查最大占用率为最大1。没有找到标准的东西,所以我写了我自己的自定义验证器,它可以做到这一点:
在模型上使用
validates_with
进行自定义验证带自定义验证器类:
摘要
1.只有当属性设置为
true
时,才会调用验证器1.检查DB是否已存在具有属性
true
的mean_of_payment.company_standard
这整件事发生在我今天上午11点后,阅读所有的评论!非常感谢!感谢您的间接帮助!:-)