I have a users table(and a user model). In my scenario, a user can have multiple identities. I.e. user michael1 (id = 1) can be connected to michael2 (id = 2) and michael3 (id = 3).
I created a table to store these connections. I called it user_relations and it has: id, user_id, related_user_id columns. In the previous example I'll have:
user_id | related_user_id
1 | 2
1 | 3
In users model I defined: has_many :user_relations, and in user_relation I defined: belongs_to :users.
Now, I want that when I have a user object I would be able to get:
current_user.user_relations - and get all users objects that are connected according to the table. In previous example, if I have current_user as user with id 1, I would like to get users with id 2 and 3.
How can I achieve that?
BTW - I have an id because I saw that without it, I am not able to use destroy_all. If anyone has an insight regarding this also, I am open to hear.
I think this should work. If I missed something you can look here for details:
class User < ActiveRecord::Base
has_many :user_relations
has_many :related_users, :through=> :user_relations
end
class UserRelations< ActiveRecord::Base
belongs_to :user, :class_name => "User", :foreign_key => "user_id"
belongs_to :related_user, :class_name => "User", :foreign_key => "related_user_id"
end
Related
I have a model called User and for my model, a user can either be a Leader or a Member. In my user model i have this
class User < ActiveRecord::Base
attr_accessible :username, :type
end
I thought i could create a many-to-many association in the User model like this
class User < ActiveRecord::Base
attr_accessible :username, :type
has_and_belongs_to_many :users, :join_table => :team_members, :foreign_key => :team_leader_id
end
But i am not really sure how to go about it. So for example.
User 1 - type :leader
User 2 - type : member
User 3 - type: member.
I want to create a relationship that can show that User 1 is the leader of user 2 and user 3.
I am still a bit new to rails .
add leader_id to User
class User < ActiveRecord::Base
attr_accessible :username, :type
belongs_to :leader, class: User
has_many :members, class: User, foreign_key: :leader_id
end
use :
#user_1 = User.create(name: "Jhon")
#user_2 = User.create(name: "Tom", leader: #user_1)
#user_1.members
well, you have User table and user can be member or leader,
if you sure that there will not be any other roles
you can use boolean leader and can be true or false if false that mean this user is member
if you not sure if there may be any other roles
you can go with what you currently being used type column and can contain member or leader that is for the first part.
then you need leader to control many members then there is 2 possibilites:
Member can belongs to only 1 Leader then you will need to add a new column in user table called leader_id for example and in this case it will be
has_many :members, :class_name => "User", :foreign_key => :leader_id
Member can belongs to many leaders then you will need to create many to many relation and then will use a new table that contain leader_id and member_id and both should be refer to user table as a forigen keys.
And better than all and have this relation in User model and its only valid for Leader you can have 2 models that inherit from User and that is called STI Single Table Inheritance you can read more about it here:
class User < ActiveRecord::Base
# this type will be checked if Leader then its Leader model if Member then its Member model
self.inheritance_column = 'type'
end
class Member < User
end
class Leader < User
has_many :members, :class_name => "User", :foreign_key => :leader_id
end
this model is away better than all, and in this case let's say in your User model you have:
1 User type='Member'
2 User type='Leaeder'
if you say:
# will work
Member.find 1
User.find 1
# will fail as type is not Leader
Leader.find 1
I have two models, Accounts and CreditRecords. An account can have many credit records that belong to it. However, accounts can also trade credit records to other accounts, and I want to keep track of who the current account owner is, and who the original owner is.
class Account < ActiveRecord::Base
has_many :credit_records
class CreditRecord < ActiveRecord::Base
belongs_to :original_owner_id, :class_name => "Account"
belongs_to :account_id, :class_name => "Account"
When I try to set a CreditRecord.account_id to, say, 1, it updates fine. But if I try to set CreditRecord.original_owner_id to 3, I get this error:
ActiveRecord::AssociationTypeMismatch: Account(#70154465182260) expected, got Fixnum(#70154423875840)
Both account_id and original_owner_id are set to be integers.
original_account_id is expecting an account object. you cannot set an id.
credit_record.original_owner = account
credit_record.account = account
or
credit_record.account_id = account.id
Please rename your association to the following
class CreditRecord < ActiveRecord::Base
belongs_to :original_owner, :foreign_key => "account_id", :class_name => "Account"
belongs_to :account
I'm not sure why you want to name your association account_id instead of just account in your CreditRecord class. The problem with this approach is when you have/will have nested resources like the following in your routes:
resources :accounts do
resources :credit_records
end
you will get a URL pattern as /accounts/:account_id/credit_records/:id/..., and your params hash will have account_id parameter in it.
Suggest updating your associations as follows as suggested by #vimsha in his answer.
class CreditRecord < ActiveRecord::Base
belongs_to :original_owner, :class_name => Account, :foreign_key => 'account_id'
belongs_to :account, :class_name => Account
end
This will allow you to assign account's id attribute through credit record object like:
# Set account's id
credit_record.account.id = 1
# Set original_owner's id
credit_record.original_owner.id = 2
I have 2 models such as User and Tracking
Tracking models has these 6 columns below
id
user_id
target_user_id
accessed_at
created_at
updated_at
The objective for this model is to know who accessed to my users/show.html.erb page.
Each user wants to know who looked at my page.
How can I make associations in both User and Tracking model?
Is it something like this?
models/user.rb
has_many: trackings
models/tracking.rb
belongs_to: user
belongs_to: user, :foreign_key => "target_user_id", :class_name => "TargetUser"
After all,
current_user.tracking.target_user shows the user whom the current_user accessed?
Then how can I retrieve the tracking records who accessed to current_user's?
How can I code in this case?
in your project there is no class with name "TargetUser",
:class_name option is to specify the name of the model you want to set association
in models/tracking.rb change your code like this,
belongs_to: user
belongs_to: target_user, :foreign_key => "target_user_id", :class_name => "User"
then you can access user from tracking by tracking.target_user
First of all your accessed_at column is redundant, you can simply delegate it like this:
delegate :accessed_at, to: :created_at
models/tracking.rb
belongs_to: tracked_user, foreign_key: 'target_user_id', class_name: 'User'
Then traverse it:
current_user.trackings.each do |t|
puts t.tracked_user_id
end
I am writing ruby on rails app, that will have 2 different types of users (let's say sellers and buyers). I was thinking about using single table inheritance, but ultimately I decided to crate 2 separate models (I believe it's better solution in my case).
The problem is when I try to create private message model (both sellers and buyers can contact each other). Typically I would just generate model called message with 3 fields (from_user_id to_user_id and content). This will not work in my case, because there might be 2 users with the same id (1 seller and 1 buyer).
I was thinking about using e-mail to identify sender and receiver, but e-mail is not my primary key, so I guess I won't be able to use it a foreign key in message model. Oh - btw, what is the best way to make sure that e-mails are unique in both sellers and buyers tables (in other words user can't join as a seller and buyer from one email)
Any ideas how I can elegantly solve my problem?
Why do you decided to not have a single User model? Considered all the issues caused by having these users in two separated tables I would have a User model and extend this model to have a Buyer model and a Seller model.
I think a buyer or a seller is still a user of your application, this resolves the problem of the message from a user to another too.
class User < ActiveRecord::Base
# Remember to add a "type" column in the users table
end
class Seller < User
end
class Buyer < User
end
The messages are now between users, no matter which kind of user.
What you are looking for is a polymorphic association. What this allows you to do is have a model that can belong to multiple other models through the same relationship by specifying the ID as well as the Class of the other object. For example, if buyer ID 3 sends a message to seller ID 5, your message table will end up with a row like:
sender_id = 3
sender_type = Buyer
receiver_id = 5
receiver_type = Seller
To accomplish this in active record, your models will look like the following:
class Message < ActiveRecord::Base
belongs_to :sender, :polymorphic => true
belongs_to :receiver, :polymorphic => true
end
class Buyer < ActiveRecord::Base
has_many :sent_messages, :class_name => "Message", :as => :sender
has_many :received_messages, :class_name => "Message", :as => :receiver
end
class Seller < ActiveRecord::Base
has_many :sent_messages, :class_name => "Message", :as => :sender
has_many :received_messages, :class_name => "Message", :as => :receiver
end
I'm trying to set up an application that includes groups that can be composed of users or existing groups.
Examples:
Users Andy, Bob, Charlie, and David are in the 1st forwarders group.
Users Eddy, Frank, George, Howard, Iggy, and Jack are in the 1st midfielders group.
Users Kenny, Lenny, Max, Ned, Oscar, Peter, and Quin are in the 1st defenders group.
User Rita is the only user in the 1st goalkeeper group.
Users Andy, Bob, Eddy, Frank, and Kenny are also in the alpha basketballers group.
Groups 1st forwarders, 1st midfielders, 1st defenders, and 1st goalkeeper are in the 1st footballers group.
Groups 1st forwarders, 2nd midfielders, 3rd defenders, and 4th goalkeeper are in the all-star footballers group.
As I understand it, this will require a polymorphic, self-referential set of models.
Based on this understanding, the three models and corresponding classes that I currently have are:
Users
- id: integer
- name: string
- plus other person-specific data
class User < ActiveRecord::Base
has_many :memberships, :as => :child
has_many :groups, :through => :memberships
end
Groups
- id: integer
- name: string
- plus other group-specific data
class Group < ActiveRecord::Base
# parental membership role
has_many :memberships
has_many :users, :through => :memberships
# child membership role
has_many :memberships, :as => :child
end
Memberships
- child_id: integer
- group_id: integer
- membership_type: string
- plus other membership-specific data
class Membership < ActiveRecord::Base
belongs_to :child, :polymorphic => true
belongs_to :group
end
When I try to access the child via something like Membership.first.child I always get a => nil response.
Do I have my models and classes set up correctly?
If not, what have I done incorrectly?
If so, how do I pull the child's information?
Or am I approaching this incorrectly, and if so, how should I approach it?
The polymorphic association columns should be child_id and child_type.