Validate the number of has_many items in Ruby on Rails

Users can add tags to a snippet:

class Snippet < ActiveRecord::Base

  # Relationships
  has_many :taggings
  has_many :tags, :through => :taggings
  belongs_to :closing_reason

end

I want to validate the number of tags: at least 1, at most 6. How am I about to do this? Thanks.

Answers


You can always create a custom validation.

Something like

  validate :validate_tags

  def validate_tags
    errors.add(:tags, "too much") if tags.size > 5
  end

A better solution has been provided by @SooDesuNe on this SO post

validates :tags, length: { minimum: 1, maximum: 6 }

I think you can validate with using .reject(&:marked_for_destruction?).length.

How about this?

class User < ActiveRecord::Base
  has_many :groups do
    def length
      reject(&:marked_for_destruction?).length
    end
  end
  accepts_nested_attributes_for :groups, allow_destroy: true
  validates :groups, length: { maximum: 5 }
end

Or this.

class User < ActiveRecord::Base
  has_many :groups
  accepts_nested_attributes_for :groups, allow_destroy: true
  GROUPS_MAX_LENGTH = 5
  validate legth_of_groups

  def length_of_groups
    groups_length = 0
    if groups.exists?
      groups_length = groups.reject(&:marked_for_destruction?).length
    end
    errors.add(:groups, 'too many') if groups_length > GROUPS_MAX_LENGTH
  end
end

Then, you can command.

@user.assign_attributes(params[:user])
@user.valid?

Thank you for reading.

References:

http://homeonrails.com/2012/10/validating-nested-associations-in-rails/ http://qiita.com/asukiaaa/items/4797ce44c3ba7bd7a51f


Need Your Help

How to use an IN clause in iBATIS?

java sql ibatis

I'm using iBATIS to create select statements. Now I would like to implement the following SQL statement with iBATIS:

Node/Express file upload

node.js file-upload express

I'm using node v0.10.26 and express v4.2.0 and I'm pretty new to node. I've been beating my head against my desk for the past three or so hours trying to get a file upload form working with node. ...