I have a profile model and it embeds_one kids_type and parent_type. As you can see in below code.
I want to validate kids_type child model. After using validates_associated, it's working fine for me.But problem is that, it validates kids_type model [#, #messages=**{:kids_type=>["is invalid"]}>**] , instead i am expecting field wise error, As i need to display inline error...
class Profile
include Mongoid::Document
validates_associated :kids_type
# PROFILE TYPE KIDS & PARENT
embeds_one :kids_type, :class_name => "ProfileKidsType"
embeds_one :parent_type, :class_name => "ProfileParentType"
end
class ProfileType
include Mongoid::Document
#COMMON FILES FOR KIDS AND PARENT
field :fname, :type => String
field :lname, :type => String
validates_presence_of :fname, :message => "ERROR: First name is required"
validates_presence_of :lname, :message => "ERROR: Last name is required"
end
class ProfileParentType < ProfileType
include Mongoid::Document
field :email, :type => String
embedded_in :profile, :inverse_of => :parent_type
end
class ProfileKidsType < ProfileType
include Mongoid::Document
field :nickname, :type => String
embedded_in :profile, :inverse_of => :kids_type
end
Any suggestion would be appreciated, Thanks in advance.
Try this here #profile is instance of Profile, it will give you all errors field wise for kids type
#profile.kids_type.errors
Related
There's Person class and PersonName class in AR, with has_many relationship. Now I want to validate the format of the PersonName model to be either alphabetic or space. Here is the code:
class Person < ActiveRecord::Base
has_many :names, :class_name => "PersonName", :dependent => :destroy
accepts_nested_attributes_for :names
end
class PersonName < ActiveRecord::Base
belongs_to :person
attr_accessible :full, :first, :middle, :last, :maiden, :title, :suffix, :nick
validates_format_of :full, :first, :middle, :last, :maiden, :title, :suffix, :nick, :with => /^[a-zA-Z\s]*$/, :on => :save
end
Seems the validates_format not get executed. When I run
PersonName.create(:full => '##$#').valid?
in the console, it returns true. I tried to change it to be :on => :create but it still return true. What could be the problem? Do I need to specify something in the Person class?
From rails documentation
Note: use \A and \Z to match the start and end of the string, ^ and $ match the start/end of a line
I think that is your problem
I found the reason, should use create! instead of create.
class Order
include Mongoid::Document
include Mongoid::Timestamps
#relationships
embeds_one :user_detail
#fields
field :description
#validations
validates :user_detail, presence: true
end
This the embedded object in order:
class UserDetail
include Mongoid::Document
include Mongoid::Timestamps
#fields
field :name, :type => String
field :zip_code, :type => String
field :email, :type => String
# Relationships
embedded_in :order
#validations
validates_presence_of :name, :zip_code, :email
end
I want save/persist on mongodb order object with user_detail object embedded_in order object.
I have tried with:
order = Order.new(description: "checking description")
order.user_detail = Order.new(:name => "John", :zip_code => "26545", :email => "john#john.com")
order.save!
but I get validation fail:
o.save!
Mongoid::Errors::Validations:
Problem:
Validation of Order failed.
Summary:
The following errors were found: User detail is invalid
Resolution:
Try persisting the document with valid data or remove the validations....
How can I fix this problem? I'm using mongoid 3.x
Should be:
order = Order.new(description: "checking description")
order.user_detail = UserDetail.new(:name => "John", :zip_code => "26545", :email => "john#john.com")
order.save!
You had Order.new for OrderDetail.new
You do not need to manually create user_detail using
order.user_detail = UserDetail.new...
order.save!
The embedded user_detail will be created automatically if u add autobuild attribute
embeds_one :user_detail autobuild: true
If u wanna persist user_detail in database as well, do not forget to add
validates_presence_of :user_detail
or you will not see the persisted user_detail in mongo db.
When doing a POST to /cloth/create I get a WARNING: Can't mass-assign protected attributes: title, description, cloth_type, pic
cloth.rb
class Cloth
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::MultiParameterAttributes attr_accessible :pics
field :title
field :description
field :cloth_type
belongs_to :seller
has_many :pics
attr_accessible :pic_attributes
accepts_nested_attributes_for:pics
end
pic.rb
class Pic
include Mongoid::Document
include Mongoid::Paperclip
has_mongoid_attached_file :image, :styles => { :medium => "300x300>", :thumb => "100x100>" },
:storage => :cloud_files,
:cloudfiles_credentials => "#{Rails.root}/config/rackspace.yml",
:path => ":attachment/:id/:timestamp_:style.:extension"
belongs_to :cloth
attr_accessible :cloth_attributes
def create
#cloth = Cloth.create!(params[:cloth])
end
end
The answer can be found here: http://api.rubyonrails.org/classes/ActiveModel/MassAssignmentSecurity/ClassMethods.html#method-i-attr_accessible
However, I will elucidate.
By setting attr_accessible :pic_attributes, you are setting a white list for what attributes can be set via mass assignment. In other words, you are saying that ONLY the attributes you've listed can be set by doing things like cloth = Cloth.new(params[:cloth]). Any other attribute you are saying should be set by using their accessors, such as cloth.title = params[:title].
If you need the attr_accessible, then add the other attributes to your list.
attr_accessible :pic_attributes, :title, :description, etc ...
I have at least 2 classes. One class must validate one of its attributes based on the value of an associated model's attributes. The below code is what I am going for, but its just an idea, it doesn't work. Any way to achieve it?
class Concert
include Mongoid::Document
include Mongoid::Timestamps
field :end_date, type: Date
end
class Sale
include Mongoid::Document
field :end_date, type: Date
belongs_to :concert
validates :end_date, :timeliness => {
:before => lambda {self.concert.end_date},
:after => lambda {self.concert.created_at},
:before_message => 'Sale should not end before the Concert begins',
:after_message => 'Sale should not end after the Concert has already ended',
:type => :date
}
end
just a guess, but isn't there a problem with your reference to self in your lambdas? I'd go for => lambda { |record| record.concert.end_date }
add validation to Sale
validates :end_date, :presence => true, :if => :some_checking
def some_checking
#your validations
#eg
self.concert.end_date.present?
end
I am trying to test an associated document for a subscription service. Each subscription is embedded in an account and references a plan. Below is the various bits of code:
The account:
Factory.define :account, :class => Account do |a|
a.subdomain 'test'
a.agents { [ Factory.build(:user) ] }
a.subscription { Factory.build(:free_subscription) }
end
The subscription:
Factory.define :free_subscription, :class => Subscription do |s|
s.started_at Time.now
s.plan { Factory.build(:free_plan) }
end
The plan:
Factory.define :free_plan, :class => Plan do |p|
p.plan_name 'Free'
p.cost 0
end
The error:
Mongoid::Errors::InvalidCollection: Access to the collection for Subscription is not allowed since it is an embedded document, please access a collection from the root document.
If I comment out the line that links the plan to the subscription then the tests work, but obviously I can't test that the subscription has a plan.
Any suggestions would be greatly appreciated.
UPDATE:
Here are the models:
class Account
include Mongoid::Document
field :company_name, :type => String
field :subdomain, :type => String
field :joined_at, :type => DateTime
embeds_one :subscription
accepts_nested_attributes_for :subscription
before_create :set_joined_at_date
private
def set_joined_at_date
self.joined_at = Time.now
end
end
class Subscription
include Mongoid::Document
field :coupon_verified, :type => Boolean
field :started_at, :type => DateTime
referenced_in :plan
embedded_in :account, :inverse_of => :subscription
end
class Plan
include Mongoid::Document
field :plan_name, :type => String
field :cost, :type => Integer
field :active_ticket_limit, :type => Integer
field :agent_limit, :type => Integer
field :company_limit, :type => Integer
field :client_limit, :type => Integer
field :sla_support, :type => Boolean
field :report_support, :type => Boolean
references_many :subscriptions
end
You need to create an account with the subscription for it to be valid.
Factory.define :free_subscription, :class => Subscription do |s|
s.started_at Time.now
s.plan { Factory.build(:free_plan) }
s.account { Factory(:account) }
end