rails belongs_to has_many please explain - ruby-on-rails

I have following:
User model with columns:
id user_id password created_at updated_at
Store model with columns:
id store_id store_name create_ad updated_at
Basically a user can belong to multiple stores. So I would want to get a query like "get all the stores that the user belongs to"
Relationships I've made are:
class User < ActiveRecord::Base
belongs_to :store, :foreign_key => "store_id"
end
class Store < ActiveRecord::Base
has_many :user, :foreign_key => "store_id"
end
are these correct?
Ultimately I want to find out whether a userid, password and storeid should be able to login.
So how can I use the find_byXXX on this ? so If I get a row back with passed in userid, password and storeId...I would know whether user should be able to login?
I noticed that belongs_to and has_many questions have been asked before but I was not able to understand well from those questions. maybe answers specific to my problem will help...

You're looking for a has_and_belongs_to_many relationship. Your tables and model should be as follows:
User Table:
id password created_at updated_at
Store Table:
id store_name created_at updated_at
Join Table (called stores_users):
store_id user_id
In your models:
class User < ActiveRecord::Base
has_and_belongs_to_many :stores
end
class Store < ActiveRecord::Base
has_and_belongs_to_many :users
end
To get a user's stores:
User.stores
See the rails API for more information.

It seems like you're making a lot of false assumptions about how ActiveRecords works on a basic level, so I would recommend reading the official and very straightforward ActiveRecord Associations guide.

So you've said that a user belongs to many stores. How many users belong to a single store?
If the answer is more than 1, then what you need is has_and_belongs_to_many and a third database table. The table will essentially contain pairs of (store_id, user_id).
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
Although it is not required by Rails, it is recommended that you create a model for this relation and make the relation bidirectional on that model. You will thank yourself later.
class User < ActiveRecord::Base
has_many :userstores
has_many :stores, :through => :userstores
end
class Store < ActiveRecord::Base
has_many :userstores
has_many :users, :through => :userstores
end
class UserStore < ActiveRecord::Base
belongs_to :user
belongs_to :store
end

Related

Order HABTM associations by created_at on the association instead of the object

I have a Match and User model with a has_and_belongs_to_many between them.
How do I retrieve match.users.first and match.users.second based on when the MatchUser association was created, rather than by when the User itself was created?
You don't want to be using has_and_belongs_to_many in the first place. has_and_belongs_to_many relations are headless - there is no join model. The only columns that are ever used on the join table are the two foreign keys. Even if you added a created_at column to the join table there is no way to access it or use it to order the records. And AR won't set the timestamps anyways.
While you can kind of assume that a has_and_belongs_to_many association is ordered in the same order that the records where inserted you can't really order it.
You want to use has_many through: which uses a model to join the two records:
class User < ApplicationRecord
has_many :user_matches
has_many :matches, through: :user_matches
end
class Match < ApplicationRecord
has_many :user_matches
has_many :users, through: :user_matches
end
class UserMatch < ApplicationRecord
belongs_to :user
belongs_to :match
end
You can then order the association by:
match.users.order("user_matches.created_at DESC")
match.users.first
will return the first user by :id.
If you want to it ordered by created_at then you must do something like
user_id = matches_users.where(match_id: match.id).first.user_id
user.find(user_id)
Hope this is what you are looking at.

Ruby on Rails 4 - How to get a has_many association for a group of users?

I have the following setup in my database. We have users. Each user has many entries. Users also belong to organizations, through a table called organization_users.
class User < ActiveRecord::Base
has_many :entries
has_many :organization_users
has_many :organizations, :through => :organization_users
end
class Entry < ActiveRecord::Base
belongs_to :user
end
class Organization < ActiveRecord::Base
has_many :organization_users
has_many :users, :through => :organization_users
end
class OrganizationUser < ActiveRecord::Base
belongs_to :user
belongs_to :organization
end
Here's my question: for a given organization, I want to get a list of all the entries for the users in that organization. Is there a nice compact way to accomplish this? I know I can iterate over all users in the organization and get the entries, but I'm not sure if there is a nice rails-y way to do this.
You can do the following assuming you have a foreign key called organization_id in organization_users table as per your Model
Entry.joins(:user => :organization_users).where("organization_users.organization_id = ?", org_id)
Where org_id is the id of the given organization. This will give you all entries of all users in an organization
Try something like that :
my_org = Organization.find(id)
my_org.users.eager_load(:entries)
First you get the organization you want to query. Then via :through association you can directly retrieve all the users for that organization. And last using eager_load, in one query you get all the entries. The result will be an ActiveRecord::Relation.

Multiple Associations With the Same Table (Many-to-Many) Ruby on Rails

I am trying to figure out the best way to accomplish a relationship and having some trouble. I have come across a few articles that somewhat address what I am looking to do but not quite.
I have a Users model and a Tickets model. Both are joined through a UserTickets model so I am able to assign multiple Users to a ticket. What I would like to do is segment the Users assigned to a Ticket into requesters and agents. The Users model does not have any columns to declare if the user is a requester or agent, rather I have is_admin, is_customer, etc. I think what I need is along the lines of Ruby On Rails - many to many between the same table but not quite.
Ideally, I'd like to have my Tickets table take agent_id's (user_id from User class) and requester_id's (user_id from User class) rather than the general user_id's (user_id from User class which combines all the users into one group). I would assume would still allow me to call #current_user.tickets to pull all the tickets that are assigned to that user.
Here is my Users model:
has_many :user_tickets
has_many :support_tickets, through: :user_tickets
Here is my Tickets model:
has_many :user_tickets
has_many :users, through: :user_tickets
Here is my UserTickets join model:
belongs_to :user
belongs_to :support_ticket
Your help is greatly appreciated!
This is not a duplicate.
#Skylar,
1) If your goal is to assign multiple Users to a ticket? Because this doesn't require a many-to-many relationship. You just need to a one-many relationship and a boolean attribute agent? on User model. You can even create am Agent model that uses User model, if you like this better.
2) However, if you wanted to create a many-to-many relationship check out this. The Rails documentation is better than I write. See section 2.6 The has_and_belongs_to_many Association.
Solution to 1)
Models
class User < ApplicationRecord
has_many :tickets, class_name: :Ticket, foreign_key: :agent_id
def agent?
self.agent
end
end
class Agent < User
default_scope { where(agent: true) }
end
class Ticket < ApplicationRecord
belongs_to :user
belongs_to :agent, class_name: :User
end
Migrations
class CreateTickets < ActiveRecord::Migration[5.0]
def change
create_table :tickets do |t|
t.references :user, index: true
t.references :agent, index: true
t.string :event_name
t.timestamps
end
end
end

Understanding use of foreign_key and class_name in association

I am new to rails and this is a very basic question. I am trying to understand the need of foreign key and class_name.
has_many :task, foreign_key: "created_by"
has_many :memberships, class_name: "TaskMembership"
Can anyone explain the need of foreign_key & class_name.
Here is the answer of my question
Suppose you have a User model and Post model.And you have to set an association like User has many post
User Model
has_many :posts
Post Model
belongs_to :user
Now suppose your user is some author so we have to set some meaningful name so instead of user we will use author but have to specify which class it is referring
Post Model
belongs_to :author, class_name: 'User'
Now problem will occur because rails will look for author_id column in posts table .So here foreign key will come into picture.We will have to find user_id
Post Model
belongs_to :author, class_name: 'User', foreign_key: 'user_id'
See more better explanation association
has_many association is used for for one-to-many type relationships in rails. For instance, if you have a model User which can has many profiles, your User to Profile association will be has many.
class User < ActiveRecord::Base
has_many :profiles
end
class Profile < ActiveRecord::Base
belongs_to :user
end
If you have a foreign key different than user_id in profiles table, you explicitly specify foreign_key. Same is the case with class name. If your association name is different than actual model name, you explicitly specify class name after association (as you did for memberships).
Hope it helps.
in your model
class First < ActiveRecord::Base
has_many :seconds
end
class Second < ActiveRecord::Base
belongs_to :first
end
and in your second class table,create first_id column

Ruby on Rails Model / Database Associations

I have a user model, farmer model, doctor model, and education model.
A farmer has a user and many educations.
A doctor has a user and many educations.
How do I setup the database for the education model?
Should it have a farmer_id AND a doctor_id?
But a education cannot belong to a farmer AND and doctor at the same time. It's one or the other.
So my education database entry would either have a farmer_id OR a doctor_id filled in, but not both.
Is there a way to guarantee that only one of the ids could be filled in at a time?
Or is there a better way to associate these models?
Your help would be appreciated!
Oh, and don't worry about the names of the models (farmer, doctor, etc.). It's just an example.
I see two possible solutions for this scenario.
The first one is to make use of polymorphic associations for education. That could look like this:
class Farmer < ActiveRecord::Base
belongs_to :user
has_many :educations, :as => :profession
end
class Doctor < ActiveRecord::Base
belongs_to :user
has_many :educations, :as => :profession
end
class Education < ActiveRecord::Base
belongs_to :profession, :polymorphic => true
end
So instead of education having a doctor_id or a farmer_id it has one profession_id and one profession_type.
The second solution would be to make use of Single Table Inheritance. And in your scenrio, that could be accomplished by letting a Doctor be a User instead of belonging to a User. And of course the same thing for a Farmer. That could look like this:
class User < ActiveRecord::Base
has_many :educations
end
class Farmer < User
end
class Doctor < User
end
class Education < ActiveRecord::Base
belongs_to :user
end
And in this scenario you would add a type column to the User model to store what type of class it is and then only having a user_id in the Education model
I think its appropriate to have the relations this way based on roles.
Class User
has_one :role
has_many :educations
end
Class Role
#What ever roles you have.
#Farmer or Doctor
belongs_to :user
end
class Education
belongs_to :user
end
This way you will store the user_id in the education object, which solves your problem.

Resources