ra_,with_options块中的验证不起作用

时间:2015-06-12 09:16:26

标签: ruby-on-rails validation

我有一个旧的Rails 2应用程序,我有一个用户模型,处理来自网络和移动应用程序的用户的配置文件。我想为网络和移动用户提供2组独立的验证。我使用DEVISE进行身份验证。

为了识别用户是否与网络或移动设备相关,我在保存/更新记录之前使用了我在控制器端设置的名为 validation_for_mobile 的attr_accessor。

似乎某些验证,特别是“ validates_length_of:password ”,即使它们位于不应评估的with_options块内,也会被执行。

在User模型中我有这段代码:

# WEB VALIDATIONS
with_options :if => "self.validation_for_mobile == false && !self.remote_sync" do |vm1|
    vm1.validates_date :birthday, :allow_blank => true
    vm1.validates_presence_of :company, :name, :surname, :address, :city, :province, :postal_code, :position, :company_type, :phone, :unless => :is_imported
    vm1.validates_format_of :phone, :with => /\A([0-9]+)\Z/i, :message => 'deve contenere solo numeri', :unless => :is_imported

    vm1.validates_presence_of :vat, :if => "!imported && !self.script_imported && company_type != 'individuale' && !company_type.blank?"
    vm1.validates_presence_of :social_number, :if => "!imported && !self.script_imported && company_type == 'individuale' && !company_type.blank? "
    vm1.validates_presence_of  :remote_id, :if => "!came_from_user && !imported && !script_imported"
    vm1.validates_acceptance_of :privacy_accepted, :privacy_third_part, :accept => true, :allow_nil => false, :unless => :is_imported
    vm1.validates_presence_of :login, :email
    vm1.validates_email_format_of :email, :message => "email non valida"
    vm1.validates_presence_of :remote_sap_code, :remote_as_code, :if => "!came_from_user"
    vm1.validates_uniqueness_of :login, :scope => :branch_id, :case_sensitive => false
    vm1.with_options :if => :password_required? do |v|
      v.validates_presence_of :password
      v.validates_confirmation_of :password
      v.validates_format_of :password, :with => /^(?=(.*\d){1})(?=.*[a-zA-Z])[0-9a-zA-Z]+$/i, :message => 'solo lettere e almeno 1 numero!'
      v.validates_length_of :password, :within => 6..10, :allow_blank => true
    end
  end


# MOBILE VALIDATIONS
with_options :if => "self.validation_for_mobile == true && !self.remote_sync" do |vm2|
  with_options :if => :mobile_validations do |vm2|
    vm2.validates_presence_of :company, :vat, :name, :surname, :phone
    vm2.validates_format_of :phone, :with => /\A([0-9]+)\Z/i, :message => 'deve contenere solo numeri'
    vm2.validates_length_of :vat, :within => 11..15
    vm2.validates_presence_of :login, :email, :branch_id
    vm2.validates_email_format_of :email, :message => "email non valida"
    vm2.validates_uniqueness_of :login, :scope => :branch_id, :case_sensitive => false
    vm2.with_options :if => :password_required? do |v|
      v.validates_presence_of :password
      v.validates_confirmation_of :password
      v.validates_format_of :password, :with => /^(?=(.*\d){1})(?=.*[a-zA-Z])[0-9a-zA-Z]+$/i, :message => 'solo lettere e almeno 1 numero!'
      v.validates_length_of :password, :within => 1..10, :allow_blank => true
    end
  end

每次尝试从移动设备创建新用户时,我都希望只评估第二个验证块,其中“ validates_length_of:password ”是“ in => 1 ..10

但我收到密码太短(至少6个字符)的错误。这是第一个阻止!!!

你能帮助我吗?

我还尝试在方法中移动with_options的条件,如下所示:

with_options :if => :web_validations
with_options :if => :mobile_validations

但没有改变。

这是我用来测试它的代码:

@user = User.new
@user.company = "Testuser"
@user.vat = "123456789012"
@user.name = "Fafag"
@user.surname = "Fafag"
@user.phone = "9182624"
@user.email = "utentest9876@test.it"
@user.login = "Utentest63"
@user.branch_id = 2

@user.password = "TEST1"
@user.password_confirmation = "TEST1"
@user.plain_password = "TEST1"

@user.mobile_signup = true
@user.mobile = true
@user.validation_for_mobile = true    # model custom validation
@user.renew_mobile_token!

@user.came_from_user = true
@user.remote_id = 0
@user.confirmed = nil
@user.active = false

if @user.save
  return true
else
  puts @user.errors.full_messages.inspect
end

1 个答案:

答案 0 :(得分:0)

好的,我解决了这个难题!

似乎嵌套with_options块不会继承外部条件。所以我必须在嵌套的with_option块中指定第一个条件,如下所示:

with_options :if => :mobile_validations do |vm2|
    vm2.validates_presence_of :company, :vat, :name, :surname, :phone
    vm2.validates_format_of :phone, :with => /\A([0-9]+)\Z/i, :message => 'deve contenere solo numeri'
    vm2.validates_length_of :vat, :within => 11..15
    vm2.validates_presence_of :login, :email, :branch_id
    vm2.validates_email_format_of :email, :message => "email non valida"
    vm2.validates_uniqueness_of :login, :scope => :branch_id, :case_sensitive => false
    vm2.with_options :if => [:password_required?, :mobile_validations] do |v2|
      v2.validates_presence_of :password
      v2.validates_confirmation_of :password
      v2.validates_format_of :password, :with => /^(?=(.*\d){1})(?=.*[a-zA-Z])[0-9a-zA-Z]+$/i, :message => 'solo lettere e almeno 1 numero!'
      v2.validates_length_of :password, :within => 1..10, :allow_blank => true
    end
  end