ActiveRecord ignores validate - ruby-on-rails

Heya im pulling my hair out right now
class Referal < ApplicationRecord
validates :pax, :presence => true
validates :customer_email, presence: true
default_scope -> { order('created_at DESC') }
self.implicit_order_column = "created_at"
belongs_to :referer, class_name: "User"
belongs_to :customer, class_name: "User"
belongs_to :business
<Referal:0x000055f8a468b058
id: nil,
state: nil,
handle: nil,
sec_code: nil,
pax: nil,
booking_date_time: nil,
business_id: "224cd62b-3d29-41ca-a1be-f308815514b2",
customer_id: nil,
referer_id: "cdfb1861-d5e4-4650-9783-4189cffde6bd",
customer_email: nil,
customer_mobile: nil,
customer_last_name: nil,
customer_first_name: nil,
created_at: nil,
updated_at: nil>
x.valid?
=> true
i tried multiple ways but it seems since i have multiple FK's in the model it only validates the ft for Business and Referer
how do i enforce the validator for additional fields? thanks

Related

Create child association from controller

I have 2 associated models and am trying to create the child from the parent's controller:
class Purchase < ActiveRecord::Base
has_many :comments, as: :commentable, dependent: :destroy
accepts_nested_attributes_for :comments, reject_if: :all_blank, allow_destroy: true
end
class Comment < ActiveRecord::Base
belongs_to :employee
belongs_to :commentable, polymorphic: true
validates_presence_of :body, :employee_id, :commentable_id, :commentable_type
end
In my controller I accept the params for comment:
def create
#purchase = Purchase.new(purchase_params)
if #purchase[:discount] && #purchase[:discount] > 0
#purchase[:discount] = #purchase[:discount].round(3)
end
if #purchase.save
render json: #purchase, status: :created
else
p "errors", #purchase.errors
render json: #purchase.errors.full_messages, status: :unprocessable_entity
end
end
private
def purchase_params
params.require(:purchase).permit(
:sale_type, :weeks, :weekly_cost, :date, :discount, :client_id, :id, :created_at, :updated_at, :employee_id, :consultation_id, :program_id, :purchaseable_type, :purchaseable_id,
comments_attributes: [:body, :id, :employee_id, :commentable_type]
)
end
When I attempt to create the purchase with the following params, I get the error:
purchase = {
client_id: client.id,
weeks: 5,
weekly_cost: 295,
comments_attributes: [{
employee_id: employee.id,
body: "This is a test",
commentable_type: "Purchase"
}]
}
#<ActiveModel::Errors:0x00007fb0ef3849e0 #base=#<Purchase id: nil, weeks: 5, weekly_cost: 295.0, created_at: nil, updated_at: nil, client_id: 18, discount: nil, employee_id: nil, comment: nil, referral_used: false, deleted_at: nil, date: nil, sale_type: nil, purchaseable_type: nil, purchaseable_id: nil, program_id: nil>, #messages={:"comments.commentable_id"=>["can't be blank"]}, #details={:"comments.commentable_id"=>[{:error=>:blank}]}>
There's no way to know the commentable_id before saving the purchase. What am I missing?

Rails rolify gem /assosiation issue

I use rolify gem with devise for AdminUser
my Roles table
class RolifyCreateRoles < ActiveRecord::Migration
def change
create_table(:roles) do |t|
t.string :name
t.references :resource, :polymorphic => true
t.timestamps
end
create_table(:admin_users_roles, :id => false) do |t|
t.references :admin_user
t.references :role
end
add_index(:roles, :name)
add_index(:roles, [ :name, :resource_type, :resource_id ])
add_index(:admin_users_roles, [ :admin_user_id, :role_id ])
end
end
model 'Role'
class Role < ActiveRecord::Base
has_and_belongs_to_many :admin_users, :join_table => :admin_users_roles
belongs_to :resource,
:polymorphic => true
validates :resource_type,
:inclusion => { :in => Rolify.resource_types },
:allow_nil => true
scopify
end
my issue is when i want to get users witch belong to role it gives empty array instead of my adminuser object
u = AdminUser.first
u.add_role(:admin)
u.roles => #<Role id: 1, name: "admin", admin_user_id: 1, resource_id: nil, resource_type: nil, created_at: "2016-06-16 15:03:33", updated_at: "2016-06-17 09:04:30">
and when i do
Role.first=> #<Role id: 1, name: "admin", admin_user_id: 1, resource_id: nil, resource_type: nil, created_at: "2016-06-16 15:03:33", updated_at: "2016-06-17 09:29:32">
Role.first.admin_users => []
To check if a user has a global role:
user = User.find(1)
user.add_role :admin # sets a global role
user.has_role? :admin
=> true
Or to check at instance level In your case
u = AdminUser.first
u.add_role(:admin)
> Role.first=> #<Role id: 1, name: "admin", admin_user_id: 1,
> resource_id: nil, resource_type: nil, created_at: "2016-06-16
> 15:03:33", updated_at: "2016-06-17 09:29:32">
Instead of doing this => Role.first.admin_users => []
Try
u = AdminUser.first
u.roles
Rolify has a pretty clear documentation
Rolify
oh i fixed it by changing relation in my admin_user model
from has_many to has_and_belongs_to_many :roles

How to make sure child object is valid while saving parent?

let say that I have two class
class User
attr_accessible :name
has_one :address
validates :name, :presence => true
validates_associated :address
end
class Address
attr_accessible :country, :user_id
belongs_to :user
validates :country, :presence => true
validates :user, :presence => true
end
Now when i try to create invalid Address then it fails(which is good)
a = Address.new
a.valid? #=> false
But when i build User with invalid Address then it pass(which is bad)
u = User.first
u.build_address
u.valid? #=> true
u.save #=> true
Due to this User has Address with country => nil.
How can i tell Rails to not save Address if its invalid?
FIXED: I fixed this by adding follow line to the code. Thank you everyone.
validates_associated :address, :if => :address
class User
attr_accessible :name
has_one :address, :validate => true
validates :name, :presence => true
validates_associated :address
end
You need to also validate that an Address is actually present for User:
class User < ActiveRecord::Base
validates :address, :associated => true, :presence => true
end
With that in place, I get:
>> u = User.first
=> #<User id: 1, name: "Bob", created_at: "2013-10-09 15:17:21", updated_at: "2013-10-09 15:17:21">
>> u.build_address
=> #<Address id: nil, user_id: 1, country: nil, created_at: nil, updated_at: nil>
>> u.valid?
=> false
>> u.errors
=> #<ActiveModel::Errors:0x007fe1d6919b18 #base=#<User id: 1, name: "Bob", created_at: "2013-10-09 15:17:21", updated_at: "2013-10-09 15:17:21">, #messages={:address=>["is invalid"]}>
>> u.address.errors
=> #<ActiveModel::Errors:0x007fe1d69197a8 #base=#<Address id: nil, user_id: 1, country: nil, created_at: nil, updated_at: nil>, #messages={:country=>["can't be blank"]}>

Cannot get accepts_nested_attributes to work in rails 3

This might be a case of me being blind…
Somehow I cannot get my layout_positions_attributes to arrive at layout_positions
l = Layout.new
…
[17] pry(main)> l.layout_positions
=> []
[18] pry(main)> l.layout_positions_attributes=[{:name=>'xxx'}]
=> [{:name=>"xxx"}]
[19] pry(main)> l.layout_positions
=> [] # WTF!
[20] pry(main)> l.layout_positions.build({:name=>'xxx'})
=> #<LayoutPosition id: nil, name: "xxx", active: true, columns: nil, rows: nil, layout_id: nil, pos: -1>
[21] pry(main)> l.layout_positions
=> [#<LayoutPosition id: nil, name: "xxx", active: true, columns: nil, rows: nil, layout_id: nil, pos: −1>]
The parent class:
class Layout < ActiveRecord::Base
attr_accessible :name, :active, :layout_positions_attributes
has_many :layout_positions
accepts_nested_attributes_for :layout_positions,
:reject_if => lambda { |a| a[:content].blank? },
:allow_destroy => true
validates_presence_of :name
end
And where the attributes should go…
class LayoutPosition < ActiveRecord::Base
attr_accessible :name, :active, :columns, :rows, :pos
belongs_to :layout
validates_presence_of :name
end
You're telling it to reject it if the content for the layout_position object is blank. In your example, above "WTF", you're not passing through any content. Therefore this is deleting the attributes.
Calling build doesn't rely on accepts_nested_attributes_for and so will work just fine.

Is there a more efficient way to create an ActiveRecord relationship on a class that references itself through another table?

I apologize if the question title is confusing. I have the following situation: I have a Person model which stores people in the standard way in the people table.
I need to add a has_many relationship for emergency_contacts on the Person model. I tried doing this in the following way:
Migrations:
create_table :people do |t|
t.string :first
t.string :middle
t.string :last
t.timestamps
end
create_table :emergency_contacts, :id => false do |t|
t.integer :person_id
t.integer :emergency_contact_id
t.timestamps
end
Models:
class Person < ActiveRecord::Base
has_many :emergency_contacts
validates :first, :presence => true
validates :last, :presence => true
end
class EmergencyContact < ActiveRecord::Base
belongs_to :person
has_one :person, :foreign_key => 'emergency_contact_id'
end
This allows me to do:
ruby-1.9.2-p180 :001 > p = Person.new(first: "John", last: "Doe")
=> #<Person id: nil, first: "John", middle: nil, last: "Doe", created_at: nil, updated_at: nil>
ruby-1.9.2-p180 :002 > ec = EmergencyContact.new
=> #<EmergencyContact person_id: nil, emergency_contact_id: nil, created_at: nil, updated_at: nil>
ruby-1.9.2-p180 :003 > ec.emergency_contact = Person.new(first: "Peter", last: "Griffin")
=> #<Person id: nil, first: "Peter", middle: nil, last: "Griffin", created_at: nil, updated_at: nil>
ruby-1.9.2-p180 :004 > p.emergency_contacts << ec
=> [#<EmergencyContact person_id: nil, emergency_contact_id: nil, created_at: nil, updated_at: nil>]
ruby-1.9.2-p180 :005 > p.save!
=> true
However, I don't feel the EmergencyContact model should have to be there, since I am really just referencing a Person model anyway.
Is there a way to remove this "middle-man" model, so that I can just do something like:
p = Person.new(first: "John", last: "Doe")
p.emergency_contacts << Person.new(first: "Peter", last: "Griffin")
I'd really use self referential associations for this kind of purpose.
Se tutorial here: http://railscasts.com/episodes/163-self-referential-association

Resources