persist embeds_one relation mongoid - ruby-on-rails

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.

Related

globalize with search_cop - unknown attribute

I'm trying to use the globalize gem and search_cop together. In my model I have:
class Museum < ApplicationRecord
include SearchCop
has_one_attached :hero_image
translates :name, :address, :description, :facilities, :hours, :tickets
search_scope :search do
attributes :name, :address
options :name, :type => :fulltext
options :address, :type => :fulltext
end
end
But when I go to search I get:
irb(main):006:0> Museum.search("art")
SearchCop::UnknownAttribute: Unknown attribute museums.name
Is it possible to use Globalize and SearchCop together? if so, how do I specify the translated fields to search on?
To use Globalize with SearchCop you need to define the translated attributes through their association. So something like:
search_scope :search do
attributes name: "translations.name", address: "translations.address"
options :name, :type => :fulltext
options :address, :type => :fulltext
end

Rails Model: save array of sub objects

I am new to Ruby and Rails. I'm try to create a "Team" object that has a leader id and an array of users attached.
Problems
I am unable to attach the array of users to the team object
I am unable to define leader object, only store its id
Any help greatly appreciated
My Rails Models:
class Team
include Mongoid::Document
include Mongoid::Timestamps::Created
include Mongoid::Timestamps::Created
field :name
field :slug
field :description
field :leader
field :users, type: Array
field :holiday_days_per_year, type: Integer
field :hours_per_day, type: Integer
field :organisation_id, type: Integer
embeds_many :users
validates :name, :holiday_days_per_year, :presence => true
validates :holiday_days_per_year, :hours_per_day, :numericality => true
before_save :set_slug
def set_slug
self.slug = "#{name.parameterize}"
end
end
class User
include Mongoid::Document
include Mongoid::Timestamps::Created
include Mongoid::Timestamps::Created
field :slug
field :first_name
field :last_name
field :birth_date, type: Date
field :job_title
field :job_start_date, type: Date
field :job_probation_ends, type: Date
field :work_email
field :work_address
field :work_phone_number
field :personal_email
field :personal_address
field :personal_phone_number
field :organisation_id, type: Integer
# emails should be unique
validates_uniqueness_of :work_email, :personal_email
validates :first_name, :last_name, :birth_date,
:job_title, :job_start_date, :job_probation_ends,
:work_address, :work_phone_number,
:personal_address, :personal_phone_number,
:presence => true
# validates emails
validates_format_of :work_email, :personal_email, :with => /\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
belongs_to :team, :inverse_of => :users
before_save :set_slug
def set_slug
self.slug = "#{first_name.parameterize}-#{last_name.parameterize}"
end
end
controller action
# POST /teams
# POST /teams.json
def create
new_params = params.permit(
:name, :holiday_days_per_year, :hours_per_day, :leader, :users)
#team = Team.new(new_params)
if #team.save
render json: #team, status: :created, location: #team
else
render json: #team.errors, status: :unprocessable_entity
end
end
JSON Sent
{
holiday_days_per_year: 20
hours_per_day: 8
leader: "522cf27114bc38307a000004"
name: "Tester"
users: [
0: "522cf27114bc38307a000004"
1: "522d966214bc38659300000d"
2: "522dd21214bc38ac6b000011"
]
}
The object is created, but users and leader dont get saved, the object comes back as
{
_id: "522df8c714bc38ef3e000022",
created_at: "2013-09-09T16:35:19.405Z",
description: null,
holiday_days_per_year: 20,
hours_per_day: 8,
leader: "522d966214bc38659300000d",
name: "Tester",
organisation_id: null,
slug: "tester",
users: [ ]
}
In your model, redefine your "as_json" method with the following
class Team < ActiveRecord::Base
..
has_many :users
def as_json(options)
{ :name=>self.name, :leader=>self.leader, :users=>self.users }
end
end

How to include only some attributes in Mongoid referenced n-n within to_json

class User
include Mongoid::Document
has_and_belongs_to_many :contacts, class_name: 'User'
field :username, :type => String
field :email, :type => String
field :time_zone, :type => String
What I want is when I call current_user.contacts.to_json to get only the username and email attributes for each contact. I tried to override to_json but doesn't seems to change anything. Any ideas?
if i understand, you can write your query like this.
User.find(:all, :select => 'email, username')

ActiveModel validate attribute based on association

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

Mongodb, child model validation?

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

Resources