Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
How can I validate a parent model, which uses accepts_nested_attributes_for
class Company < ActiveRecord::Base
include CompanyRepository
PHONES_NUMBER_MIN = 1
EMAILS_NUMBER_MIN = 1
attr_accessible :name, :state_event, :payment_method_id, :tariff_id, :status_id, :assigned_id,
:category_id, :referer, :rental_fee,
:contact_details_attributes, :counteragents_attributes, :gis_objects_code_list
acts_as_taggable_on :gis_objects_codes
composed_of :rental_fee, ComposeOfParams.money(:rental_fee_in_kop)
belongs_to :payment_method
belongs_to :tariff
belongs_to :category
belongs_to :status
belongs_to :creator, :class_name => ::Employee, :foreign_key => 'employee_id'
belongs_to :assigned, :class_name => ::Employee, :foreign_key => 'assigned_id'
has_many :contact_details, :as => :contactable, :dependent => :destroy
has_many :people, :dependent => :destroy
has_many :invoices, :dependent => :destroy
has_many :deals, :dependent => :destroy
has_many :accounts, :dependent => :destroy
has_many :crm_accounts, :dependent => :destroy
has_many :gis_accounts, :dependent => :destroy
has_many :notes, :dependent => :destroy, :order => 'created_at DESC'
has_many :events, :dependent => :destroy, :class_name => ::Employee::Event
has_many :counteragents, :dependent => :destroy
has_many :counteragent_kinds, :through => :counteragents,
:class_name => 'Counteragent::Kind', :source => :kind, :uniq => true
validates :name, :presence => true, :uniqueness => {:case_sensitive => false}, :length => {:maximum => 255}
validates :creator, :presence => true
validates :assigned, :presence => true
validates :rental_fee, :numericality => { :greater_than_or_equal_to => 0 }, :allow_nil => true
validates_each :rental_fee do |record, attr, value|
record.errors.add(attr, :not_a_number) if value.is_a?(NilMoney)
end
validate do |company|
check_emails_number if our_client?
check_phones_number
end
after_initialize :init
accepts_nested_attributes_for :contact_details, :allow_destroy => true, :reject_if => :contact_details_invalid
accepts_nested_attributes_for :counteragents, :allow_destroy => true
state_machine :state, :initial => :active do
state :active
state :deleted
before_transition :on => :del do |company|
company.people.active.map &:del
company.deals.active.map &:del
company.accounts.active.map &:del
company.unassigned_events.active.map &:del
end
event :del do
transition :active => :deleted
end
end
def to_s
name
end
def our_client?
status.our_client? if status.present?
end
def cars_count
counteragents.collect{ |c| c.cars_count || 0 }.sum
end
# Public: Sets nil if value is blank, calls super otherwise
#
# value - The String value
def rental_fee_with_empty_string_processing=(value)
value = nil if value.is_a?(String) && value.empty?
self.send('rental_fee_without_empty_string_processing=', value)
end
alias_method_chain :rental_fee=, :empty_string_processing
# FIXME [Anton Kalyaev 09/07/2012] we cannot guarantee that it is true main email
def main_email
contact_details.emails.try :first
end
def main_phone
contact_details.phones.try :first
end
private
def init
if new_record?
self.rental_fee ||= 0.0
end
end
def phones_number_valid?
kind = ContactDetail::Kind.phone
phones = contact_details.select { |cd| cd.kind_id == kind.id }
phones.size >= PHONES_NUMBER_MIN
end
def check_phones_number
unless phones_number_valid?
errors.add(:base, :phones_too_short, :count => PHONES_NUMBER_MIN)
end
end
def email_number_valid?
kind = ContactDetail::Kind.email
emails = contact_details.select { |cd| cd.kind_id == kind.id }
emails.size >= EMAILS_NUMBER_MIN
end
def check_emails_number
unless email_number_valid?
errors.add(:base, :email_too_short, :count => EMAILS_NUMBER_MIN, :our_client_name => Status.our_client.name)
end
end
def contact_details_invalid(attributes)
# validate emails
unless our_client?
email_kind_id = ContactDetail::Kind.email.id
if attributes['kind_id'] == email_kind_id.to_s && attributes['kind_value_source'].blank?
return true
end
end
false
end
end
class ContactDetail < ActiveRecord::Base
include ContactDetailRepository
attr_accessible :kind_id, :kind_value_source
belongs_to :contactable, :polymorphic => true
belongs_to :kind
validates :kind_value_source, :presence => true, :length => {:maximum => 255}
# custom validation
validates :kind_value, :contact_detail_uniqueness => {:case_sensitive => false}, :phone => true, :if => :phone?
validates :kind_value, :contact_detail_uniqueness => {:case_sensitive => false}, :email => true, :if => :email?
validates :kind_value, :contact_detail_uniqueness => {:case_sensitive => false}, :url => true, :if => :site?
def to_s
kind_value_source || kind_value
end
def phone?
kind == ContactDetail::Kind.phone
end
def email?
kind == ContactDetail::Kind.email
end
def site?
kind == ContactDetail::Kind.site
end
def kind_value_source=(v)
value = v
write_attribute(:kind_value_source, value) # save original value
if phone?
value = Filters.phone(v)
end
if site?
value = Filters.site(v)
end
self.kind_value = value
end
end
class ContactDetail::Kind < ActiveRecord::Base
include UsefullScopes
attr_accessible :name, :slug
validates :name, :presence => true, :length => {:maximum => 255}
validates :slug, :slug => true, :uniqueness => true
def to_s
name
end
class << self
def phone
find_by_slug(:phone)
end
def email
find_by_slug(:email)
end
def site
find_by_slug(:site)
end
end
end
module ContactDetailRepository
extend ActiveSupport::Concern
include UsefullScopes
included do
scope :phones, where(:kind_id => ContactDetail::Kind.phone)
scope :emails, where(:kind_id => ContactDetail::Kind.email)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.