Ruby on rails Rails:摆脱泛型;“X无效”;验证错误

Ruby on rails Rails:摆脱泛型;“X无效”;验证错误,ruby-on-rails,validation,nested-attributes,Ruby On Rails,Validation,Nested Attributes,我有一个注册表单,它包含嵌套的关联/属性,您可以随意调用它们 我的层次结构如下: class User < ActiveRecord::Base acts_as_authentic belongs_to :user_role, :polymorphic => true end class Customer < ActiveRecord::Base has_one :user, :as => :user_role, :dependent => :dest

我有一个注册表单,它包含嵌套的关联/属性,您可以随意调用它们

我的层次结构如下:

class User < ActiveRecord::Base
  acts_as_authentic
  belongs_to :user_role, :polymorphic => true
end

class Customer < ActiveRecord::Base
  has_one :user, :as => :user_role, :dependent => :destroy
  accepts_nested_attributes_for :user, :allow_destroy => true
  validates_associated :user
end

class Employee < ActiveRecord::Base
  has_one :user, :as => :user_role, :dependent => :destroy
  accepts_nested_attributes_for :user, :allow_destroy => true
  validates_associated :user
end

由于嵌套用户模型中至少有一个无效字段,因此会在错误列表中添加一条额外的“X无效”消息。这会让我的客户感到困惑,因此我想知道是否有一种快速的方法可以做到这一点,而不必自己处理错误。

使用验证后方法

  def after_validation
    # Skip errors that won't be useful to the end user
    filtered_errors = self.errors.reject{ |err| %w{ user User  }.include?(err.first) }
    self.errors.clear
    filtered_errors.each { |err| self.errors.add(*err) }
  end
编辑

注:-

在您的案例中,在下面的列表中添加用户。如果有多个由空格分隔的关联,则可以添加多个

%w{ User user }.include?(err.first) #### This piece of code from the above method has logic which reject the errors which won't be useful to the end user

萨利尔的回答几乎是对的,但他从未做到100%。以下是正确的方法:

def after_validation
    # Skip errors that won't be useful to the end user
    filtered_errors = self.errors.reject{ |err| %{ person }.include?(err.first) }

    # recollect the field names and retitlize them
    # this was I won't be getting 'user.person.first_name' and instead I'll get
    # 'First name'
    filtered_errors.collect{ |err|
      if err[0] =~ /(.+\.)?(.+)$/
        err[0] = $2.titleize
      end
      err
    }

    # reset the errors collection and repopulate it with the filtered errors.
    self.errors.clear
    filtered_errors.each { |err| self.errors.add(*err) }
  end

好的,这看起来很有希望!:)我想你在“Note:-”下面有个语法错误,这让我很困惑。。“添加…??”另外,我应该把这个函数放在哪里?在每一个模型中都是这样做的?这是来自ARB的函数重写吗?对不起,语法:)。把这个方法放在你写的每一个模型中,验证你的关联,好吧,我现在就投票给你,因为这大部分是有效的。但有一个问题:与此相反:登录太短(最少3个字符)密码太短(最少4个字符)密码确认太短(最少4个字符)我得到的是:User.Login太短(最少3个字符)User.Password太短(最少4个字符)User.password confirmation太短(最少4个字符),如果您能找到解决方法,我将接受您的回答。此外,我提出了一个功能请求,作为更好的解决方案,然后解决此问题:我遇到错误“没有将符号隐式转换为字符串”@Chemist这是为旧版本的rails工作的。请尝试编辑提供的代码,使其与您现在使用的版本正常工作。@Chemist-要修复“符号到字符串的隐式转换”,请将
%{}
更改为
%w{}
,尽管在Rails 4.1中,我注意到您需要使用符号数组(
%I{}
def after_validation
    # Skip errors that won't be useful to the end user
    filtered_errors = self.errors.reject{ |err| %{ person }.include?(err.first) }

    # recollect the field names and retitlize them
    # this was I won't be getting 'user.person.first_name' and instead I'll get
    # 'First name'
    filtered_errors.collect{ |err|
      if err[0] =~ /(.+\.)?(.+)$/
        err[0] = $2.titleize
      end
      err
    }

    # reset the errors collection and repopulate it with the filtered errors.
    self.errors.clear
    filtered_errors.each { |err| self.errors.add(*err) }
  end