I have the following model in rails (simplified):
class Phone < ActiveRecord::Base
include ActiveModel::Validations
belongs_to :user
belongs_to :brand
attr_readonly :user, :brand
attr_accessible :model, :phone_number
validates :user, :presence => true
validates :brand, :presence => true
validates :model, :presence => true
validates :phone_number, :presence => true
end
According to the documentation, attr_readonly should allow attributes to be set at creation, but not at update.
However, when I do this:
Phone.create(:user => <existing_user>, :brand => <existing_brand>, :model => "Galaxy", :phone_number => "555-433-5678")
I get this error:
Can't mass-assign protected attributes user, brand
What am I missing?
If you want to assign a user and a brand association like that, you must define them as being accessible attributes:
attr_accessible :user, :brand
Otherwise, you can assign them like this:
Model.create({:user => user, :brand => brand }, :without_protection => true)
Related
When updating car info, the validation process fails because I have validates_uniqueness_of :number
class Car < ActiveRecord::Base
validates :number,numericality: true, length: {is: 7 }
validates :number, :name, presence:true
validates_uniqueness_of :number, :message => "מספר רכב זה קיים במערבת"
belongs_to :owner
has_many :visits
end
I need validation to pass, if the original value was not changed, validation on_create would not help since I still need validation when updating.
Any help would be really appreciated.
This will work for you :
validates :number, :uniqueness => {:scope => :number}, :message => "מספר רכב זה קיים במערבת"
OR
validates_uniqueness_of :number, :message => "מספר רכב זה קיים במערבת", :scope => :number
How do I create a Factory that has multiple associations that rely on the same parent?
The Parent model:
class Parent < ActiveRecord::Base
has_many :codes
has_many :parent_filters
validates :parent, :presence => true, :uniqueness => true
end
The Fitler model:
class Filter < ActiveRecord::base
has_many :parent_filters
validates :filter, :presence => true, :uniqueness => true
end
The ParentFilter join model:
class ParentFilter < ActiveRecord
belongs_to :parent
belongs_to :filter
validates :filter, :presence => true
validates :parent, :filter, :presence => true, :uniqueness => [ :scope => filter ]
end
The AdhocAttribute model:
class AdhocAttribute < ActiveRecord::Base
has_many :adhoc_mappings
has_many :codes, :through => :adhoc_mappings
has_many :parent_filters, :through => adhoc_mappings
validates :adhoc_attribute, :presence => true, :uniqueness => true
end
The code model:
class Code < ActiveRecord::Base
belongs_to :parent
has_many :adhoc_mappings
has_many :adhoc_attributes, :through => :adhoc_mappings
validates :code, :parent, presence: true
validates :code, uniqueness: {case_sensitive: false}
end
And last but not least, an ad-hoc mapping model. This model allows for each code to be assigned one adhoc attribute per ParentFilter, which is the factory that I'm trying to create. This factory should require that the Parent for both the ParentFilter and the Code be the same (I'll add a custom validation to enforce that once I get a functional factory).
class AdHocMapping < ActiveRecord::Base
belongs_to :code
belongs_to :parent_filter
belongs_to :adhoc_attribute
has_one :company, :through => :parent_filter
validates :code, :parent_filter, presence: true
validates :code, :uniqueness => { :scope => :parent_filter }
end
If I were to create an AdhocMapping using straight ActiveRecord, I would build it up something like this:
p = Parent.where(:parent => "Papa").first_or_create
aa = AdhocAttribute(:adhoc_attribute => "Doodle").first_or_create
f = Filter.where(:filter => "Z..W").first_or_create
c = Code.where(:code => "ZYXW", :parent => p).first_or_create
pf = ParentFilter.where(:parent => p, :filter => f).first_or_create
am = AdhocMapping(:adhoc_attribute => aa, :parent_filter => pf, :code => :c).first_or_create
so that the Code and ParentFilter that is assigned to the AdhocMapping have the same Parent. I've tried a number of different methods to try to get this to work in FactoryGirl, but I can't seem to get it to create the object.
Here is the factory I thought was the closest to what I want:
require 'faker'
FactoryGirl.define do
factory :adhoc_mapping do |f|
transient do
p Parent.where(:parent => Faker::Lorem.word).first_or_create
end
association :parent_filter, :parent => p
association :code, :parent => p
association :adhoc_attribute
end
end
It gives an error of Trait not registered: p
For associations I usually use after(:build) in FactoryGirl, then I can exactly tell what should happen. (association xxx often did not work like I wanted it to, shame on me.)
So in your case I think you can solve it with this:
require 'faker'
FactoryGirl.define do
factory :adhoc_mapping do |f|
transient do
default_parent { Parent.where(parent: Faker::Lorem.word).first_or_create }
parent_filter { FactoryGirl.build(:parent_filter, parent: default_parent) }
code { FactoryGild.build(:code, parent: default_parent) }
adhoc_attribute { FactoryGirl.build(:adhoc_attribute) }
end
after(:build) do |adhoc_mapping, evaluator|
adhoc_mapping.parent_filter = evaluator.parent_filter
adhoc_mapping.code = evaluator.code
adhoc_mapping.adhoc_attribute = evaluator.adhoc_attribute
end
end
end
By using after(:build) it works with either FactoryGirl.create or FactoryGirl.build. In addition with the transient default_parent, you can even explicitly set the parent you want to have when you build your adhoc_mapping. And now after edit you can also pass nil to the attributes and it will not get overridden.
I have products and brands
products model:
class Product < ActiveRecord::Base
attr_accessible :brand_id, :title
belongs_to :brand
validates :title, :presence => true
validates :brand, :presence => {:message => 'The brand no exists'}
end
and the brands model
class Brand < ActiveRecord::Base
attr_accessible :name
validates :name, :presence => true
has_many :products, :dependent => :destroy
end
I want to validate if exist a product with a name in this brand.
I mean I could have 2 products with the same name in different brands but not in the same brand.
You could use the uniqueness validation with a scope:
validates :name, :uniqueness => { :scope => :brand_id }
Note that you have to specify :brand_id instead of :brand, because the validation can't be made on the relation.
If you don't know it, I suggest you to read the Active Record Validations and Callbacks guide.
NB: the syntax {:foo => 'bar'} is replaced (since Ruby 1.9.2) with {foo: 'bar'}.
Following is my models:
class Poll < ActiveRecord::Base
attr_accessible :published, :title
validates :published, :presence => true
validates :title, :presence => true,
:length => { :minimum => 10 }
has_many :choice, :dependent => :destroy
end
class Choice < ActiveRecord::Base
belongs_to :poll
attr_accessible :choice_text, :votes
validates :choice_text, :presence => true
end
I then tried to install the rails admin. I was able to create the choices and polls in the admin, but i was unable to associate a choice with a poll and vice versa.
How can i do it?
First of all in has_many class name should be in plural:
has_many :choices
And you should add attr_accessible poll_id or choice_ids for Model from which you want to edit this association. Or just delete all attr_accessible for first try.
class Poll < ActiveRecord::Base
attr_accessible :published, :title, choice_ids
validates :published, :presence => true
validates :title, :presence => true, :length => { :minimum => 10 }
has_many :choices, :dependent => :destroy
end
class Choice < ActiveRecord::Base
belongs_to :poll
attr_accessible :choice_text, :votes, :poll_id
validates :choice_text, :presence => true
end
There is no attr_accessible in Rails 4. Use accepts_nested_attributes_for instead. More info:
https://github.com/sferik/rails_admin/wiki/Belongs-to-association
I am trying to write a unit testing for a User model in Ruby on Rails. I am using authlogic and need to check that the first_name and last_name of the user model attributes are not the same when the user is registering.
This is my user model:
class User < ActiveRecord::Base
acts_as_authentic do |c|
c.login_field= :username
end
has_many :memberships, :class_name => "Project::Membership"
has_many :projects, :through => :memberships
has_one :profile
validates :email, :presence => true, :uniqueness => true
validates :username, :presence => true, :uniqueness => true
validates :first_name,:presence => true
validates:last_name, :presence => true
validates :title, :presence => true
validates :password, :presence => true
validates :password_confirmation, :presence => true
validates :gender, :presence => true
# Custom validator
validates :first_name, :last_name, :different_names => true
As you can see, I tried to create a custom validator creating a new file in /lib/different_names_validator.rb with a class called DifferntNamesValidator, but couldn't get it, as I got the following error: Unknown validator: 'different_names' (ArgumentError)
Thanks in advance!
Hi Try to include this module in your model