循环自定义验证方法中的属性

时间:2018-01-19 13:41:53

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-4

我想循环使用自定义验证方法验证的属性。 我的模型Post has_many :languages和模型Language belongs_to :post。在languages表中,我有列 - id, post_id, language

发布模型:

class Post < ApplicationRecord
  has_many :languages

  accepts_nested_attributes_for :languages, reject_if: :all_blank
  validates_associated :languages
end

语言模型:

class Language < ApplicationRecord

  validate :unique_languages?

  def unique_languages?
    #LOOP ATTRIBUTES
  end
end

Language中的unique_languages?模型我希望过度遍历帖子的所有语言属性。 这是posts_controller,具有强大的参数和创建帖子的逻辑:

class PostsController < ApplicationController

  def new
    @post = Post.new
    @post.languages.build if @post.languages.empty?
  end

  def create
    @post = Post.new(post_params)
    @post.languages.build if @post.languages.empty?
    if @post.save
      redirect_to action: 'new'
    else
      render 'new'
    end
  end

  private

  def post_params
    params.require(:post).permit(:title, languages_attributes: [:language])
  end
end

2 个答案:

答案 0 :(得分:1)

## app/validators/nested_attributes_uniqueness_validator
class NestedAttributesUniquenessValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    raise ArgumentError if options[:parent].blank?

    association = record.class.to_s.pluralize.underscore # :languages
    items =
      record                    # @language
        .send(options[:parent]) # @language.post
        .send(association)      # @language.post.languages
        .select(attribute)      # @language.post.languages.select(:language)

    unless items.distinct.size == items.size
      record.errors.add attribute, :nested_attributes_uniqueness
      # Don't forget to translate `errors.messages.nested_attributes_uniqueness`
    end
  end
end


## app/models/post.rb
class Post < ApplicationRecord
  has_many :languages, inverse_of: :post # :inverse_of is important

  accepts_nested_attributes_for :languages, reject_if: :all_blank
end


## app/models/language.rb
class Language < ApplicationRecord
  belongs_to :post, inverse_of: :languages # :inverse_of is important

  validates :language, nested_attributes_uniqueness: { parent: :post }
end

答案 1 :(得分:0)

您可以通过以下方式访问对象属性:

class Language < ApplicationRecord

   validate :unique_languages?

   def unique_languages?
     self.attributes.each do |attr, value|
       #your code
     end
   end
end

your object.attributes返回一个哈希,其中键是属性名称,值是该属性的值。不确切地知道你要做什么,但这可能会有所帮助。祝你好运!