Need to Use Add_Index on Migration for Belongs_To/Has_Many Relationship? (Rails 3.2, Active Record)

Need to use add_index on migration for belongs_to/has_many relationship? (Rails 3.2, Active Record)

You do need to add the index yourself... However, if you use the command line generator for the model and use belongs_to, Rails will add in the index into the migration...

e.g.

rails g model product deal:belongs_to

would produce

class CreateProducts < ActiveRecord::Migration
def change
create table :products do |t|
t.belongs_to :deal

t.timestamps
end
add_index :products, :deal_id
end
end

A migration to add unique constraint to a combination of columns

add_index :people, [:firstname, :lastname, :dob], unique: true

Multiple foreign keys referencing the same table in RoR

This sounds like a has_many relationship to me - put the customer_id in the Address table instead.

Customer
has_many :addresses

Address
belongs_to :customer

You can also provide a foreign key and class in the assoc declaration

Customer
has_one :address
has_one :other_address, foreign_key => "address_id_2", class_name => "Address"

Associations and (multiple) foreign keys in rails (3.2) : how to describe them in the model, and write up migrations

add_index adds an index to column specified, nothing more.

Rails does not provide native support in migrations for managing foreign keys. Such functionality is included in gems like foreigner. Read the documentation that gem to learn how it's used.

As for the associations, just add the columns you mentioned in your Question to each table (the migration you provided looks fine; maybe it's missing a :rule_id?)

Then specify the associations in your models. To get you started

class Question < ActiveRecord::Base
has_many :options
has_many :assumption_rules, class_name: "Rule"
has_many :consequent_rules, class_name: "Rule"
end

class Rule < ActiveRecord::Base
belongs_to :option
belongs_to :assumption_question, class_name: "Question", foreign_key: :assumption_question_id, inverse_of: :assumption_rules
belongs_to :consequent_question, class_name: "Question", foreign_key: :consequent_question_id, inverse_of: :consequent_rules
end

class Option < ActiveRecord::Base
belongs_to :question
has_one :rule
end

Note This is just a (untested) start; options may be missing.

I strongly recommend you read

  • http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
  • http://guides.rubyonrails.org/association_basics.html

Edit: To answer the question in your comment

class Option < ActiveRecord::Base
belongs_to :question
# ...

The belongs_to tells rails that the question_id column in your options table stores an id value for a record in your questions table. Rails guesses the name of the column is question_id based on the :question symbol. You could instruct rails to look at a different column in the options table by specifying an option like foreign_key: :question_reference_identifier if that was the name of the column. (Note your Rule class in my code above uses the foreign_key option in this way).

Your migrations are nothing more than instructions which Rails will read and perform commands on your database based from. Your models' associations (has_many, belongs_to, etc...) inform Rails as to how you would like Active Record to work with your data, providing you with a clear and simple way to interact with your data. Models and migrations never interact with one another; they both independently interact with your database.

Rails Converting a has_many relationship into a has and belongs to many

I suggest you to always use has_many :through instead of HBTM.

To establish this kind of relation you'll need the following set up:

# region.rb
class Region
has_many :facility_regions
has_many :facilities, through: :facility_regions
end

# facility.rb
class Facility
has_many :facility_regions
has_many :regions, through: :facility_regions
end

# facility_region.rb
class FacilityRegion
belongs_to :facility
belongs_to :region
end

Also, of course, you'll need to create a migration:

rails g migration create_facility_regions facility_id:integer region_id:integer
# in this migration create a uniq index:
add_index :facility_regions, %I(facility_id region_id), name: :facility_region
rake db:migrate

UPD

As to migration from one database state to another one.

I think it should not be a problem.

1) Do not delete the relations you had before (leave has_many :facilities and belongs_to :region in models).

2) When new table is created and new associations added to the classes (which I showed) create a new migration:

rails g migration migrate_database_state

3) Write the script, which will create new records in db (to reflect the current state of things):

ActiveRecord::Base.transaction do
Facility.where.not(region_id: nil).find_each do |facility|
next if FacilityRegion.find_by(falicity_id: facility.id, region_id: facility.region_id)
FacilityRegion.create!(facility_id: facility.id, region_id: facility.region_id)
end
end

4) Put this script into last created migration and run it (or in console without migration, effect would be the same).

5) After script is successfully run, create new migration in which you delete region_id from facilities table and remove these associations definitions (has_many :facilities and belongs_to :region) from models.

It must be it. I might have made some typos or so, make sure I did not miss anything and

Does has_many realation require foreign key?

The foreign keys should be defined in your migration. If you use the generator, Rails will generate a migration, which maybe looks like the following:

class CreateQuotes < ActiveRecord::Migration
def change
create_table :quotes do |t|
t.string :title, null: false
t.text :content, null: false

t.references :user
t.timestamps
end
end
end

The statement t.references :user will generate your foreign key column, which is called user_id in this case.

Here is a quote from the Rails Guides:

Using t.integer :supplier_id makes the foreign key naming obvious and explicit. In current versions of Rails, you can abstract away this implementation detail by using t.references :supplier instead.

Does belongs_to creates an association in Rails 5?

Does belongs_to creates an association in Rails 5?

Yes.

belongs_to is an alias of references and it:

  • creates person_id column in items table;
  • adds index on person_id column.


Related Topics



Leave a reply



Submit