Ruby on rails - Link to the same model twice?

Is it possible to establish a double bond in activerecord models using the generate scaffold command?

For example, if I had a User model and a PrivateMessage model, the pm table would have to track both sender and recipient .

Obviously, for one relationship, I would just do this:

 ruby script/generate scaffold pm title:string content:string user:references 

Is there a similar way to establish two relationships?

Also, is there a way to set up aliases for relationships?

So, instead of saying:

 @message.user 

You can use something like:

@message.sender or @message.recipient

Any advice is appreciated.

Thank.

+47
ruby-on-rails rails-activerecord relationship relationships
Jan 13
source share
5 answers

Add this to your model.

 has_one :sender, :class_name => "User" has_one :recipient, :class_name => "User" 

And you can call @message.sender and @message.recipient and both links to the user model.

Instead of user:references in your generation team, you will need sender:references and recipient:references

+56
Jan 13 '10 at 14:21
source share

Here is a complete answer to this question if people visiting this question are new to Ruby on Rails and have difficulty putting everything together (as I did when I first studied this question).

Some parts of the solution take place in your migrations, and some in your models:

Migrations

 class CreatePrivateMessages < ActiveRecord::Migration def change create_table :private_messages do |t| t.references :sender t.references :recipient end # Rails 5+ only: add foreign keys add_foreign_key :private_messages, :users, column: :sender_id, primary_key: :id add_foreign_key :private_messages, :users, column: :recipient_id, primary_key: :id end end 

Here you indicate that in this table there are two columns that will be called: sender and: recipient and which contain links to another table. Rails will actually create columns for you with the names 'sender_id' and 'receient_id'. In our case, they will refer to rows in the Users table, but we indicate this in models, and not in migrations.

models

 class PrivateMessage < ActiveRecord::Base belongs_to :sender, :class_name => 'User' belongs_to :recipient, :class_name => 'User' end 

Here, you create a property in the PrivateMessage model with the name: sender, and then indicate that this property is associated with the User class. Rails, seeing "own_to: sender", will look in your database for a column named "sender_id", which we defined above, and use it to store the foreign key. Then you do the same for the recipient.

This will allow you to access your Sender and Recipient, both instances of the User model, through an instance of the PrivateMessage model, for example like this:

 @private_message.sender.name @private_message.recipient.email 

Here is your user model:

 class User < ActiveRecord::Base has_many :sent_private_messages, :class_name => 'PrivateMessage', :foreign_key => 'sender_id' has_many :received_private_messages, :class_name => 'PrivateMessage', :foreign_key => 'recipient_id' end 

Here you create a property in the user model called sent_private_messages, indicating that this property is associated with the PrivateMessage model and that the foreign key in the PrivateMessage model that associates it with this property is called "sender_id". Then you do the same for the private messages you receive.

This allows you to receive sent or received private messages from all users by doing something like this:

 @user.sent_private_messages @user.received_private_messages 

Executing any of them will return an array of PrivateMessage model instances.

....

+117
Apr 21 2018-12-21T00:
source share

hi there so that both lateral relationships do as shown below in both models:

 class Message < ActiveRecord::Base belongs_to :sender, :class_name => "User", :foreign_key => "sender_id" belongs_to :recipient, :class_name => "User", :foreign_key => "recipient_id" end class User < ActiveRecord::Base has_many :sent, :class_name => "Message", :foreign_key => "sent_id" has_many :received, :class_name => "Message", :foreign_key => "received_id" end 

I hope this helps you ...

+18
May 23 '11 at 12:43
source share

The above answers, although excellent, do not create foreign key constraints in the database, but only bigint indexes and columns. To enforce foreign key constraints, add the following to your migration:

 class CreatePrivateMessages < ActiveRecord::Migration[5.1] def change create_table :private_messages do |t| t.references :sender t.references :recipient end add_foreign_key :private_messages, :users, column: :sender_id, primary_key: :id add_foreign_key :private_messages, :users, column: :recipient_id, primary_key: :id end end 

This ensures that indexes are created in sender_id and recipient_id , as well as foreign key constraints in the database used.

+9
Sep 13 '17 at 1:50
source share

So ... can I do the same through the Rails g scaffold?

Thank you for your time.

0
Jan 25 '19 at 0:57
source share



All Articles