How to search in Ruby on Rails - ruby-on-rails

I have the three models:
class Joinedtravel < ApplicationRecord
belongs_to :travel
belongs_to :user
end
class Travel < ApplicationRecord
has_many :joinedtravels
belongs_to :user
end
class User < ApplicationRecord
has_many :joinedtravels
has_many :travels
end
How can I obtain all travels that a user has joined in the past?
I did something like that:
#user = User.find(id)
#past_travels = Travel.where('travels.data < ?', DateTime.now)
#all_joinedtravels = #user.joinedtravels.travels
but i don't kwon how to correctly join the results.

First you need to fix the relationship
class Joinedtravel < ApplicationRecord
belongs_to :travel
belongs_to :user
end
class Travel < ApplicationRecord
has_many :users, through: joinedtravels
has_many :joinedtravels
end
class User < ApplicationRecord
has_many :travels, through: joinedtravels
has_many :joinedtravels
end
Then you can simply search it using
User
.find(id)
.travels
.where('travels.data < ?', DateTime.now)

This should work:
#user = User.find(id)
#past_joinedtravels = #user.joinedtravels.joins(:travels).where('travels.date < ?', DateTime.now)
Try this in the console, and pay attention to the sql produced. That will show you possible errors.
The travelsin the joins clause is the model name. The travelsin the where clause must be the literal database table name, which I just guessed.

Seems to me you'd be better off using a has_and_belongs_to_many relations and a join table to join the User and Travel models as long as you're not including any additional information in the JoinedTravel model?
https://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association
class Travel < ApplicationRecord
has_and_belongs_to_many :user
end
class User < ApplicationRecord
has_and_belongs_to_many :travels
end
#user = User.find(id)
#past_travels = Travel.where('travels.data < ?', DateTime.now)
#user_travels = #user.travels
You could then see if a user has any travels:
#user.travels.present?

Related

Polymorphic has_many through Associations in Ruby on Rails

I have the following problem,
A user can have several professions, more than 10. For example, a user may be a doctor, teacher, and N. Each profession has its own attributes.
I could do, Doctor belongs_to User, but if I want to know all the professions of this user I will have to check each row of the User table.
I created the following code
class User < ApplicationRecord
has_many :jobables
end
class Job < ApplicationRecord
belongs_to :user
belongs_to :jobable
end
class Jobable < ApplicationRecord
has_one :job
end
class Medic < Jobable
end
class Programmer < Jobable
end
But I do not know if that would be the best answer
I would think that it would be much easier to do something like:
class User < ApplicationRecord
has_many :user_professions
has_many :professions, through: :user_professions
end
# == Schema Information
#
# Table name: professions
#
# id :integer not null, primary key
# name :string
# created_at :datetime not null
# updated_at :datetime not null
#
class Profession < ApplicationRecord
has_many :user_professions
has_many :users, through: :user_professions
end
class UserProfession < ApplicationRecord
belongs_to :user
belongs_to :profession
end
You could then create logic to ensure that a Profession is only assigned to a User once.
Then, you could simply do:
#user.professions
And get all the Professions for a User.
You could also do:
#profession.users
And get all the Users that belong to the Profession.
Based on the edit to your question, you could do something like:
class UserProfession < ApplicationRecord
belongs_to :user
belongs_to :profession
belongs_to :profession_detail, polymorphic: true
end
In which case you might have something like:
class DoctorDetail < ApplicationRecord
end
And you could do something like:
#user.professional_detail_for(:doctor)
Of course, you would need to implement the professional_detail_for method on the User model which might look something like:
class User < ApplicationRecord
has_many :user_professions
has_many :professions, through: :user_professions
def professional_detail_for(profession_type)
user_profession_for(profession_for(profession_type)).try(:profession_detail)
end
private
def profession_for(profession_type)
Profession.find_by(name: profession_type.to_s)
end
def user_profession_for(profession)
user_professions.find_by(profession: profession)
end
end
That's a little rough, but I imagine you get the idea.

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 })

Rails .where statement with nested resources

I'm struggling with a .where statement in an index action.
In my Deals controller, i'd like to list all the deals where the bank of the current_user is participating.
Below are my models :
class User < ActiveRecord::Base
belongs_to :bank
end
class Deal < ActiveRecord::Base
has_many :pools
end
class Pool < ActiveRecord::Base
belongs_to :deal
has_many :participating_banks, dependent: :destroy
has_many :banks, through: :participating_banks
end
class ParticipatingBank < ActiveRecord::Base
belongs_to :pool
belongs_to :bank
end
Here is my Deals Controller Index action :
def index
#deals = Deal.all
end
I don't find any way to say : 'I only want to see a deal if this deal has, at least, one pool where the current_user.bank has been added'.
Any idea?
Many thanks :)
You should do inner join and query joined table for id. You can easily do it in Rails by:
def index
#deals = Deal.joins(pools: :banks).where(banks: { id: current_user.bank_id })
end

Activerecord proper associations

I have four models
Bid Order User Printer
currently I cannot access the order through anything except User.
I would like to be able to do something of the sort bid.order but have yet to figure out the correct association. Any thoughts?
class Bid < ActiveRecord::Base
belongs_to :printer
end
class Order < ActiveRecord::Base
belongs_to :user
has_many :bids
end
class Printer < ActiveRecord::Base
has_many :orders, through: :bids
has_many :bids
end
class User < ActiveRecord::Base
has_many :orders
end
Both models must know about the relationship so you need to state that in the Bid model
class Bid < ActiveRecord::Base
belongs_to :printer
belongs_to :order
end

How to get value of some column of association table in Rails?

how can I get a weight of product through a Record model? As I know, possible to get all products of certain record but I cannot find out the way getting the weight of certain product.
class User < ActiveRecord::Base
has_many :eatings
end
class Eating < ActiveRecord::Base
belongs_to :user
has_many :records
end
class Record < ActiveRecord::Base
belongs_to :eating
end
class Product < ActiveRecord::Base
end
class WeightedProduct < ActiveRecord::Base
end
What relationships should have Record and Product models with WeightedProduct so user will be able to get weight of certain product through one line User.first.eatings.first.records.first.products.first.weight?
Looks like you're after this:
class Record < ActiveRecord::Base
belongs_to :eating
has_many :weighted_products
end
class Product < ActiveRecord::Base
has_many :weighted_products
end
class WeightedProduct < ActiveRecord::Base
belongs_to :record
belongs_to :product
end
Then User.first.eatings.first.records.first.weighted_products.first.weight
I think that should work but haven't tested.
it seems that each product has one weighted product, then in that case you should add
class Product < ActiveRecord::Base
has_one :weighted_product
end
class WeightedProduct < ActiveRecord::Base
belongs_to :product
end
and
class Record < ActiveRecord::Base
belongs_to :eating
has_many :products
end

Resources