Is my first time building a custom validation , since trying to the regular ORM validations did not work. I have a model called AdGroup which belongs to another model called Car. I want to send prevent that a user creates a new Ad Group if they have not selected a car. Also the Car is a file.
class AdGroup < ActiveRecord::Base
belongs_to :car
validate :validate_car_id
def validate_car_id
car = Car.find_by(id: params[:id])
if car.nil?
errors.add(:car, "Select a car image")
end
end
end
class Car < ActiveRecord::Base
validates :make, :model, :year, presence: true
validates :file, presence: true
belongs_to :make
has_many :ad_groups
...
end
Is an image that I am trying to select .
Your Ad Group model needs to be associated with the Car model. AdGroup models should have belongs_to :car line and the Car model needs has_many :ad_groups.
To validate associated models you could use ActiveRecord's validates_associated. Be sure to read the docs by the link for gotchas.
class AdGroup < ActiveRecord::Base
belongs_to :car
validates :car, presence: true
validates_associated :car
end
When using validates_associated you don't have to do custom validation.
Related
I have two models Person and Address:
class Person < ApplicationRecord
has_one :address
end
class Address < ApplicationRecord
belongs_to :person
end
How do I validate that each points to the other?
I want to do something similar to:
class Person < ApplicationRecord
has_one :address
validates :address, presence: true
end
Of course this doesn't work because address is not an attribute on Person.
What is the correct way in Rails to ensure that a record has a valid association with another record?
class Person < ApplicationRecord
has_one :address, required: true
end
class Address < ApplicationRecord
belongs_to :person
end
See the required option in the options section of https://apidock.com/rails/v5.2.3/ActiveRecord/Associations/ClassMethods/has_one
belongs_to in Rails 5 is now automatically required so you don't need to put anything different inside of Address.
You need to use validates_associated :address to validate associations
I have these two models
User.rb
has_one :bike
Bike.rb
belongs_to :user
If a user tries to create multiple bikes, then the has_one relation doesn't make sense.
How can I add validation for this condition in the model level?
How can I make sure that the user will be always having one bike?
Create a before_create callback in bike.rb file. Check if the current_user.bike has any record or not. If record exists then add an error and return.
class Bike < ApplicationRecord
# Associations
has_one :user
before_create :user_exists
private
def user_exists
if self.user.bike.present?
errors[:base] << "Add your validation message here"
return false
end
end
end
You can simply add a validates_uniqueness_of call on your Bike model.
class Bike < ApplicationRecord
belongs_to :user
validates_uniqueness_of :user_id
end
I have created my model:
class Vehicle < ActiveRecord::Base
belongs_to :player
has_one :basis
has_one :carcass
has_one :weapon
end
How I can make this model able to save itself ONLY when it got its player, basis, carcass, weapon? What I need to ad to my validation?
You can validate the state of objects before they go into the database using Active Record's validations feature.
In your Vehicle model, define your validations as follows:
class Vehicle < ActiveRecord::Base
belongs_to :player
has_one :carcass
has_one :weapon
validates :player, presence: true
validates :carcass, presence: true
validates :weapon, presence: true
end
This should prevent your Vehicle to be saved if any of your references is missing.
Good luck!
Edit
You can shorten the validation rules:
validates :player, :carcass, :weapon, presence: true
I am trying to create a has_one association among two model.
class User < ActiveRecord::Base
has_one :emergency_contact
end
class EmergencyContact < ActiveRecord::Base
belongs_to :user
end
when i try to test it through rails console more than one entries are saved for the emergency contact model for a single user. Although when i retrieve it using User.emergency_contact only the first entry is returned. When saving how can i make it to rollback for more than one entry
You can simply validate uniqueness of user_id column in EmergencyContact:
class EmergencyContact < ActiveRecord::Base
belongs_to :user
validates_uniqueness_of :user_id, allow_nil: true
end
I have a has many through relationship in my app:
Shows has many Bands through => Lineups
Bands are unique by :name
class Show < ActiveRecord::Base
attr_accessible :city_id, :title, :dateonly, :timeonly, :image, :canceled, :venue_attributes, :bands_attributes
belongs_to :city
belongs_to :venue
has_many :lineups
has_many :bands, through: :lineups
has_and_belongs_to_many :users
end
class Lineup < ActiveRecord::Base
belongs_to :show
belongs_to :band
end
class Band < ActiveRecord::Base
attr_accessible :name, :website, :country, :state
has_many :lineups
has_many :shows, through: :lineups
validates :name, presence: true
validates_uniqueness_of :name
before_save :titleize_name
private
def titleize_name
self.name = self.name.titleize
end
end
New Bands are created like this:
(lets say we have a show record already saved called s1)
> s1.bands.new(name: "Wet Food")
> s1.save
Right now this will only save if a band named "Wet Food" doesn't already exist
In which model is the best place to do a Band.find_or_create in this relationship so that an existing band can be used if one with the same name exists?
This is generally the type of call that would go in a Controller (or maybe a service object), but not in a Model. It really depends on the particular user flow that you're trying to accomplish in your app. Basically, where ever you are already using s1.bands.new, you could use this instead :
s1.bands.where(name: 'Wet Food').first_or_create