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 initems
table; - adds index on
person_id
column.
Related Topics
Alter $Path in Vim/Macvim So as to Find the Right Ruby Binary
Fastercsv Error with Ruby 1.9.2
How to Use Variables in a Yaml File
Gem Which Cannot Find Gem Despite It Being Installed
How to Use Objects with Xsi:Types in Savon
Making a Module Inherit from Another Module in Ruby
Graphql::Client::Dynamicqueryerror Expected Definition to Be Assigned to a Static Constant
How to Make Xcode Use the Correct Version of Ruby When Running a Script
Ruby Elegant Way to Return Min/Max If Value Outside Range
How to Force Rails to Load All Models
Uninitialized Constant > Actioncable::Server::Configuration::Applicationcable
JSON::Parsererror: 757: Unexpected Token at '{
How to Sign_In for Devise to Test Controller with Minitest
Is It a Good Idea to Purge Old Rails Migration Files
Rails: Detecting User Agent Works in Development But Not Production