Rails has many associations

I have few questions that turn me off, and I need to answer. Everything is connected with the next two-many-many study guide .

Question 1

Do I need to have a has_many identifier in the connection table? or its best practice for removing an identifier? and add an index and use two other primary keys and set it unique and together?

Question 2

How can this be done when migrating table creation?

Question 3

After completing this relationship model and updating the data. I would like to create a new dataset every time it is updated (to save data). How will the controller look in an update, new, to create a model?

Question 4

In the middle table, I would like to set attributes that have visible true or false, as I can set not only the third table, but also the arguments of the second table

+4
source share
2 answers

First ... caution: this railscast is very old. In this episode there may be syntactic things that were dated by new versions of rails.


Question 1

If you use the has_many through method, you must have an id column in the connection model because you are using a full-scale model . As Ryan mentions in the episode, you will choose this method if you need to track additional information. If you use the has_and_belongs_to_many method, you will not have an id column in your table.

If you want to receive a check in which you do not allow duplicates in your many-to-many association (ie Allow the pairing of element a with element b and again allow another entry of element a to element b), you can use a simple validates a row with scope:

validates_uniqueness_of :model_a_id, :scope => [:model_b_id] 


Question 2

You can add indexes to your migrations with this code.

 add_index :table_name, [ :join_a_id, :join_b_id ], :unique => true, :name => 'by_a_and_b' 

This will be added to the change block below your create_table statement (but not in that create_table block). Check this question for more details: In the join table, what is the best workaround for missing a Rails complex key?


Question 3

I donโ€™t quite understand what you want to do, but if you want to take some action every time a new record is inserted into the join model, I would use the active capture of the after_create record. It will look something like this.

 class YourJoinModel < ActiveRecord::Base after_create :do_something def do_something puts "hello world" end end 

This do_something function will be called every time a new record is created.


Question 4

Using the has_many method will give you access to additional attributes that you defined in this model on either side of the relationship. For example, if you have this setting:

 class Factory < ActiveRecord::Base has_many :widgets, :through => :showcases end class Widget < ActiveRecord::Base has_many :factories, :through => :showcases end class Showcases < ActiveRecord::Base belongs_to :factory belongs_to :widget attr_accessiable :factory_id, :widget_id, :visible end 

Could you say something like

 widget = Widget.first shown = widget.showcases shown.first.visible 

or

 shown = widget.showcases.where( :visible=> true ) 

You can also contact another association:

 shown.first.factory 
+3
source

The reason for having an id column in an association is that it gives you the ability to delete that particular association without touching yourself with its relationship. Without this association identifier, it is difficult to determine outside of all foreign keys.

For the trivial case, when you have only two components for your key, this is not a big distinguishing feature, but often you will have three or more as part of your unique constraint, and where things get complicated.

Having an id also makes relationships a top-notch model. This can be useful when you are manipulating elements that are associated with metadata. It also means that you can add metadata effortlessly later. This is what you mean by your โ€œQuestion 4โ€. Add these attributes to the join model.

Typically, a join model is created, like any other model. The primary key is id , and you create a series of additional keys:

 create_table :example_things |t| t.integer :example_id t.integer :thing_id end add_index :example_joins, [ :example_id, :thing_id ], :unique => true add_index :example_joins, :thing_id 

The unique index serves to prevent duplication and allows you to search for key pairs. The second is to retrieve all example_id for the given thing_id .

The usual way to manipulate metadata in a join model is to fetch directly:

 @example_things = @example.example_things.includes(:thing) 

This loads the ExampleThing and Thing models associated with the example.

0
source

All Articles