Get current object on has_many side when saving - ruby-on-rails

I am creating an Event that has many Equipments. I want to validate the Equipment model. How can I access the equipment's event that I am currently saving? I need that to get the date when the equipment will be used(date is known from Event model). Here is the code:
class Event < ApplicationRecord
has_many :equipment_events, class_name: EquipmentEvent
has_many :equipment, through: :equipment_events
end
class Equipment < ApplicationRecord
has_many :equipment_events
has_many :events, through: :equipment_events
validate :equipment_already_used
def equipment_already_used
date = # <== HERE I need the date from this equipment's event that I am saving
end
end

You need to move the validation from Equipment to EquipmentEvent, since Equipment and Event are independent entities.
class EquipmentEvent < ApplicationRecord
belongs_to :equipment
belongs_to :event
validate :equipment_already_used
def equipment_already_used
event.date # <== HERE
end
end

Related

Activerecord associations and migrations

I have a model Ride. A ride has one driver and one user
Im trying to implement a Rating for the the rides
Each Rating must belong to a ride.
Id like to have the associations and models such that I can call
Driver.ratings and it gives me all ratings for that driver(through the rides table)
and call User.ratings gives me a list of all ratings for that user(through the rides table)
class Ride < ApplicationRecord
belongs_to :driver, optional: true
belongs_to :user, optional: true
end
class User < ApplicationRecord
has_many :rides
end
class Driver < ApplicationRecord
has_many :rides
end
You will have to use has_many through associations
In your Drive and User model, you can add following associations
class Driver < ApplicationRecord
has_many :rides
has_many :ratings, through: :rides
end
class User < ApplicationRecord
has_many :rides
has_many :ratings, through: :rides
end

Guarantee that model is associated to same parent

Assuming i have 3 models associated to each other:
class Farm < ApplicationRecord
has_many :horses
has_many :events
end
class Horse < ApplicationRecord
belongs_to :farm
has_many :events_horses, class_name: 'Event::EventsHorse'
has_many :events, through: :events_horses, source: :event, dependent: :destroy
end
class Event
belongs_to :farm
has_many :events_horses, class_name: 'Event::EventsHorse'
has_many :horses, through: :events_horses, source: :horse, dependent: :destroy
end
class Event::EventsHorse < ApplicationRecord
self.table_name = "events_horses"
belongs_to :horse
belongs_to :event
audited associated_with: :event, except: [:id, :event_id]
end
How to guarantee that each of the Horse belongs to same Farm as event? Possible solution is using custom validation, but i was wondering if there is some other way. I have few other models like Horse, so it force me to do custom validation method to each of them.
class Event
...
validate :horses_belongs_to_farm
private
def horses_belongs_to_farm
horses.all? {|h| h.farm_id == farm_id}
end
end
I think the model you are using is setting up too many id's between the tables that require consistency checking.
If you set the model up this way, then you don't need to validate that a horse's farm and event are consistent since the data ensures it:
class Farm < ApplicationRecord
has_many :horses
has_many :events
end
class Horse < ApplicationRecord
belongs_to :farm
has_many :events, through: :farm
end
class Event < ApplicationRecord
belongs_to :farm
has_many :horses, through: :farm
end
If you need efficient access to horses from events or events from horses, you can use joins. This gives some simplicity, clarity, and consistency.
You should also have a look at Choosing Between has_many_through and has_and_belongs_to_many.
[Edit based upon updated question and comments] Now that your model and question are a little more clear, my hunch is that putting the validation in the Event model causes redundant validations. Since your intent is to make sure that, in a given event, the horse and farm are consistent, I would put the validation in EventsHorses:
class Event::EventsHorse < ApplicationRecord
...
validate :horse_belongs_to_farm
private
def horse_belongs_to_farm
horse.farm_id == event.farm_id
end
end
As an aside, thy do you have Event::EventsHorse rather than simply have a separate model for EventsHorse?

How to use foreign keys in Ruby on the Rails query?

I have three models; events, users and entries. I would like on my users page for to be able to retrieve information relating to the events associated with the event associated with the user.
def show
#user = User.find(params[:id])
#entry = #user.entries.paginate(page: params[:page])
end
It is more than happy with #user.entries.count but I would like to link up in a table something like this:
Event Name - Event Location - Course
My models are bellow:
class Event < ApplicationRecord
has_many :entries, dependent: :destroy
class User < ApplicationRecord
has_many :entries, dependent: :destroy
class Entry < ApplicationRecord
belongs_to :user
belongs_to :event
If they're related as:
class User < ApplicationRecord
has_many :events
end
class Event < ApplicationRecord
has_many :entries
belongs_to :user
end
class Entry < ApplicationRecord
belongs_to :event
end
Then you can use joins starting from Entry, up to User and check events where the user id is the one what you need:
Entry.joins(event: :user).where(users: { id: user_id })

How do I assign items that belong to one half of "has many :through" with the other half of the association?

I'm trying to model my database in Ruby and can't figure out how to do it.
This is what I have so far:
class Course < ActiveRecord::Base
has_many :enrolled_ins
has_many :users, :through => :enrolled_ins
has_many :events, :dependent => :destroy
end
class User < ActiveRecord::Base
has_many :enrolled_ins
has_many :courses, :through => :enrolled_ins
end
class EnrolledIn < ActiveRecord::Base
belongs_to :users
belongs_to :courses
end
class Event < ActiveRecord::Base
belongs_to :courses
end
I want to add that when a user picks a course, they can select the different events that they want with that course, and those are assigned to them instead of them getting all the events.
I would add a UserEvents join. When you add a course, you would see a list of available events. Assuming you have a form with checkboxes, you would create the UserEvent records. I don't think you would need all 3 ID values (user, event, course). Course is just a way to group the various events.
class UserEvent < ActiveRecord::Base
belongs_to :user
belongs_to :event
end
I'd also add a dependent destroy on user and on event do destroy the join records if either side is removed.

Recording the date an object is added to a has_many collection

Users on my site each have one list, which consists of a different type of users. I'm using a has_many through relationship to do this as follows:
List.rb:
class List < ActiveRecord::Base
belongs_to :company
has_many :list_applicants
has_many :applicants, through: :list_applicants
end
Applicant.rb:
class Applicant < ActiveRecord::Base
has_many :list_applicants
has_many :lists, through: :list_applicants
end
ListApplicant.rb
class ListApplicant < ActiveRecord::Base
attr_accessible :applicant_id, :list_id
belongs_to :applicant
belongs_to :list
end
Company.rb:
class Company < ActiveRecord::Base
has_one :list
end
When a user adds another user to their list, I'd like to record the date the user is added so they can sort their list of users by date added. What is the best way to do this?
You can use the created_at field of the ListApplicant model if it has one. If not, you may add manually a similar field.
UPDATE:
You can access the field by specifying both applicant and list like this:
#applicant.list_applicants.where(list_id: #list.id).first.created_at

Resources