I execute the following commands to make the model:
script/generate model user firstname:string lastname:string
script/generate song group songname:string songtitle:string
a user has_many :songs and a song belongs_to :user
after this I run rake db:migrate however, the associations are not carried to my actual DB. Because in my actual DB I do not see any user_id column in songs table...etc.
Do we have to manually change the migration and add the needed columns?
To the best of my knowledge, you need to explicitly add the user_id to the migration file or when you are generating the model. I do now know of a way for it to detect the association and create the user key at least from the generate line:
I believe your options are:
script/generate song group songname:string songtitle:string user_id:integer
Or in the migration - adding this to your migration file:
t.integer :user_id
Or also adding this to your migration file. I don't believe you can do this from the command line. And you will need to do it after you create the belongs_to :user association in your songs.rb model.
t.references :user
As a note, I generally take the second option.
One other aside just on general ruby/rails convention - generally attribute names are lowercase and separated by underscores. so song_name instead of songname. That is entirely a taste thing and up to you as to how you want to implement.
I hope this helps!
Related
I have a table named product_categories. And I wanna create an self-relationship. What is the right way to do it using migrations generate command? I did this and it didnt work:
rails g migration AddProductCategoryToProductCategories productcategory:references
Just to summarize what worked in the comment section.
You must use
product_category
instead of
productcategory
Rails uses _ as a separator between names, called snake case. This can all be a little bit confusing when beginning to use Rails, and indeed even after using Rails for a long time. The guides are your friend...
http://edgeguides.rubyonrails.org/active_record_migrations.html
http://edgeguides.rubyonrails.org/association_basics.html
Generally speaking, the table name can be whatever you want it to be. I for one sometimes find Rails naming conventions a bit whacky.
If you've already generated the product_categories and products models/ tables, then just do:
rails generate model product_categories_products product_id:integer product_category_id:integer
This will generate a model that stores both foreign keys and acts as a proxy table.
You would then need to set up Product model with:
has_many product_categories_products
has_many product_categories, through: product_categories_products
Then define the following in ProductCategory
has_many product_categories_products
has_many products, through: product_categories_products
And Finally in ProductCategoryProduct
belongs_to product
belongs_to product_category
However, the above naming convention is horrible. You'd be better off renaming ProductCategory to just 'Category' and then your proxy table model can be 'ProductCategory'.
...or you could renaming it something completely different and then just manually specify the class_name in the association definitions.
I've got two tables in my Postgres database: categories and products.
I have a one to many relationship defined, one category can have many products.
After I've defined these in the two models in Rails, is there something else I need to do to the tables? I still have only the primary key that Rails defined when I set up each model separately.
You can run a migration generator with the right parameters to set up the foreign key.
bin/rails generate migration AddCategoryRefToProducts category:references
This assumes you have a Product model and Category model with these associations:
#product.rb
belongs_to :category
#category.rb
has_many :products
Run rake db:migrate to complete the process
When you look at your db/migrate directory you will see a file that contains an add_reference line within a def change block. Here's the reference for that method: Rails API. The syntax for the standalone generator is from the Rails Guides
I have a table that currently belongs to 2 different models. What I'd like to do is turn these into a polymorphic association instead.
Currently the table line_items have a cart_id and an order_id now what I'd like to do is migrate both of these ids into a polymorphic one called itemable_id and fix the itemable_type to the correct one.
How would I go about creating a migration for this, or what's the go-to solution for this case, where you have two ids columns and want to make it polymorphic?
Try following and add belongs_to :itemable, polymorphic: true in LineItem model
rails generate migration RemoveCartRefFromLineItems cart:references
rails generate migration RemoveOrderRefFromLineItems order:references
rails g migration AddItemableIdToLineItems itemable_id:integer
rails g migration AddItemableTypeToLineItems itemable_type:string
I am new to RoR. I used "rails generate model ServiceConfigs" command to generate a table.
so may commands are as below
rails generate model ServiceConfigs configs:string
rake db:migrate
-- can see app/db/service_config.rb created.
Now edited service_config.rb file to add 2 columns and which has a foreign key relation to service table. So here is code
class ServiceConfigs < ActiveRecord::Base
belongs_to :service, :dependent => :destroy
validates_presence_of :configs
end
Now when I login to underline database, and look at the table I don't see foreign key relation in table schema. Whats wrong/more I need to do?
highly appreciate your time and help
Krishna
So a few notes for you as you're getting started here: Firstly, I'd name your model in the singular form, as though you are describing a single instance of it: ServiceConfig and in the case where it belongs to a service, you may want to think of a different name all together.
Secondly validates_presence_of suggests that you have that field, so firstly, I'd remove the validation until you know that your DB has that column and that the migration worked. You can make sure by looking at your migration file and confirming that the column is being created.
You can define the relationship the "rails way" in your migration too:
http://guides.rubyonrails.org/association_basics.html
create_table :service_configs do |t|
t.string :configs
t.references :service
t.timestamps
end
Update
If you want to rerun a particular migration run:
rake db:migrate:redo VERSION=20100421175455
You can take a look in your schema to see what migration you are currently at as well. And you can also take a look at the schema to see what your DB is expected to look like as well.
I am new to rails (usually a python guy) and have just been trying to build a simple task manager application for fun. I am using Devise for authentication and have a single Task object I am trying to relate to a user. I have added the following to the Task model:
class Task < ActiveRecord::Base
belongs_to :user
end
and I have added the following in my User model for Devise:
class User < ActiveRecord::Base
has_many :tasks
<<normal Devise stuff>>
end
Whenever I added this information I then ran: rake db:migrate. It then gave me an error that the database field did not exist for user_id when I tried to do anything with it.
I am sure it is something rather simple that I am missing. Thanks for the help.
Adding a belongs_to (or any other) relationship to your model only tells active record that models are linked logically. This gives you access to methods like task.user. For this to actually work, the instances must be linked via database fields.
This is the step you're missing: you need to create a migration that will add a column to the Task table indicating which user it belongs to.
rails g migration AddUserIdToTasks user_id:integer
Note AddUserIdToTasks can be whatever name you want. It makes no difference. You can then open db/migrations/add_user_to_tasks and see what it does. Usually self.up will modify the database how you want it and self.down will do the opposite (so, in this case, remove the used_id).
Then to actually execute the SQL commands to alter the database table and schema, run
rake db:migrate
You need to generate a migration to add the foreign key first:
rails g migration AddUserIdToTasks user_id:integer
Then run db:migrate
And if you want the user to be able to reference the association as user.dreams, you need to add :class_name => 'Task' to the has_many line in the User model.
Your user class seems to be too dreamy to take care of it's tasks.
has_many :dreams // should be probably
has_many :tasks
Assuming that you tasks model has a user_id field, that is.