Rails 3: belongs_to, has_one and Migrations
You have to add the foreign key in your migration file, something like this:
def change
create_table :songs do |t|
t.references :artist
end
add_index :songs, :artist_id
end
Rails 3 has_one / belongs_to relationship with model in subdirectory
Looks like I got it to work. I'm sharing and annotating my result for others to learn.
In model/user.rb
class User < ActiveRecord::Base
has_one :email_sub, :class_name => "Subscriptions::EmailSub"
before_create :build_email_subscription
private
def build_email_subscription
build_email_sub(:announcements => true, :notifications => true, :master => true)
true
end
end
I expressly include the class_name
to find the model in the subdirectory. I used the build_<attribute>
and passed in the parameters for three subscriptions (later to come in from a form but for now just setting defaults).
In model/subscriptions/email_sub.rb
class Subscriptions::EmailSub < ActiveRecord::Base
attr_accessible :announcements, :daily_deals, :master
belongs_to :user
end
(I left the attributes out above since they're not really relevant to the issue but I'll expressly include them here for beginning users.)
Instead of a new migration I modified the original migration for the EmailSubs model.
class CreateSubscriptionsEmailSubs < ActiveRecord::Migration
def change
create_table :subscriptions_email_subs do |t|
t.boolean :master
t.boolean :daily_deals
t.boolean :announcements
t.references :user # I added this line to the generated migration
t.timestamps
end
end
end
I added the t.references
line. Note that I had it plural before and not singular (in a migration the table name needs to be plural, the field singular). t.references will know to look for the _id field given .
Hopefully this can help save some others some time.
Rails has_one and belongs_to migration?
It would be easiest for you to keep with rails naming conventions. If I got it correctly, a business belongs to a Type/Category. let the business reference the type. add a belongs_to on the business side and a has_many on the type/category side. Roughly like this:
class Business < ActiveRecord::Base
attr_accessible :description, :email, :facebook, :foursquare, :google, :manager, :mobile, :name, :phone, :type_id, :url, :yelp
belongs_to :type
end
class Type < ActiveRecord::Base
has_many :businesses
end
class CreateTypes < ActiveRecord::Migration
def change
create_table :types do |t|
t.string :category
t.timestamps
end
end
end
class CreateBusinesses < ActiveRecord::Migration
def change
create_table :businesses do |t|
t.string :name
t.string :url
t.string :phone
t.string :manager
t.string :email
t.boolean :mobile
t.boolean :foursquare
t.boolean :facebook
t.boolean :yelp
t.boolean :google
t.text :description
t.integer :type_id
t.timestamps
end
end
end
has_many, belongs_to relation in active record migration rails 4
You could call:
rails g model task user:references
which will generates an user_id
column in the tasks
table and will modify the task.rb
model to add a belongs_to :user
relatonship. Please note, you must to put manually the has_many :tasks
or has_one :task
relationship to the user.rb
model.
If you already have the model generated, you could create a migration with the following:
rails g migration AddUserToTask user:belongs_to
which will generate:
class AddUserToTask < ActiveRecord::Migration
def change
add_reference :tasks, :user, index: true
end
end
the only difference with this approach is, the belongs_to :user
relationship in the task.rb
model won't be created automatically, so you must create it for your own.
Rails: Create migrations for has_many and has_one
Your migrations are correct, because if you think of your models as in database tables, you will never store the 'has_many' option somewhere. That is merely for the human understanding, as well as for ActiveRecord.
So an option in your example belongs to a question, hence we have to store the ID of that question in the record of the answer. In the question migration however, we don't store any information regarding the option, it is enough that the option "knows" which question it belongs to. (And same for user and question).
Only in the model you can then specify - as you did - the 'has_many' options. This will allow you later to call 'question.options` to retrieve all options that belong to a question.
Rails, using a belongs_to and has_one association to the same class
interactions
table just needs a victim_id
column and then change the has_one
to belongs_to :victim, class_name: Player
.
This will work since an Interaction
is basically a join table of Player
to Player
.
has_one
implies that the victim (Player
in this case) would have a interaction_id
which is incorrect.
Instead an Interaction
belongs to the killer and the victim.
Setup as:
class Player
has_many :kills, class_name: Interaction, foreign_key: :player_id inverse_of: :killer
has_many :deaths, class_name: Interaction, foreign_key: :victim_id, inverse_of: :victim
end
class Interaction
belongs_to :killer, class_name: Player, foreign_key: :player_id, inverse_of: :kills
belongs_to :victim, class_name: Player, foreign_key: :victim_id, inverse_of :deaths
end
Reverse association for belongs_to - has_one
No, has_one
does not affect your database. belongs_to
is what will actually create a foreign key field in your table, that is why you need a migration.
Mixing has_one and has_and_belongs_to_many associations
Why are you using HABTM here at all? Just put a belongs_to :category
on Link, and a has_many :links
on Category. Then in the db, you don't need a join table at all, just a :category_id on the links table.
But, if you do want a HABTM here, from a quick glance, the first thing I noticed is that your join table is named incorrectly -- it should be alphabetical, categories_links
.
The second thing is that you can't mix has_one and has_and_belongs_to_many. HABTM means just that -- A has many of B and A belongs to many of B; this relationship implies that the opposite must also be true -- B has many of A and B belongs to many of A. If links HABTM cateogries, then categories must HABTM links.
See http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_and_belongs_to_many
Rails 4 has_one relation
If Order has one table then table needs the order's foreign key. So you actually run the opposite migrations. Table should have order_id foreign key.
def change
add_reference :tables, :order, index: true
add_foreign_key :tables, :orders
end
Then create a table record with order_id and call Order#table.
Can Model A has_one Model B that has_and_belongs_to_many Model A?
has_and_belongs_to_many
is intended to be used symmetrically; in other words, if the Platform model uses it to point to Company, then the Company model should use it to point to Platform. Trying to pair it with another type of association should fail, and is failing.
If you want company.platform.name
to work, have you considered the has_many
relationship? Like this:
class Company < ApplicationRecord
belongs_to :platform
end
class Platform < ApplicationRecord
has_many :companies
end
This type of relationship does not need a join table. Instead it uses the platform.company_id
column mentioned in your error message.
Related Topics
How to Collapse Double Splat Arguments into Nothing
Using the Right Exception Subclass in Ruby
Openssl Causing Very Slow Rails Boot Time on Windows
Error Requiring Pg Under Rvm with Postgres.App
Why Aren't "Gem" and "Bundle" Using the Same Libxml2
How to Get the Real File from S3 Using Carrierwave
Rewrite Template.Js.Erb into Template.Js.Slim
Sorting Numeric Strings in Ruby
Error When Starting Sinatra: "Tried to Create Proc Object Without a Block"
How to Combine Multiple Arrays of the Same Size in Ruby
Ruby's "Foo = True If !Defined? Foo" Won't Work as Expected
Openssl::Ssl::Sslcontext Sni Servername_Cb Not Working
Recursively Convert Hash Containing Non-Utf Chars to Utf
Regex "Punct" Character Class Matches Different Characters Depending on Ruby Version
Working with Multiple Processes in Ruby
How to Use Multiple Models for Tag_Cloud
Gem::Ext::Builderror: Error: Failed to Build Gem Native Extension. on Cenos 6.5