So i'm making a Rails application to learn how to use the framework.
I created a user using:
rails g model User name:string
Then I realized my user also needed another attribute and a relationship with another resource called user_role.
Say my UserRole model is something like:
rails g model userRole roleName:string
So far I've found that I can only achieve the change using a migration, but this is rather inconvenient and unclear to me, since I don't really have any old data, I'm just adjusting my model.
Any advise for a noob?
Migration is extremely helpful. It keeps track of your schema changes. However, if you find that you forgot to add an field immediately after creating migration, you can edit the old migration without creating a new. If you already migrated your database (using rake db:migrate) you can rollback.
rake db:rollback
Now, edit the migration file and add/remove you fields. When completed, migrate again
rake db:migrate
When you create a separate model, you SHOULD create a separate migration. Otherwise, in future you will be confused yourself. btw, when creating children model, you don't need any change in the parent migration. you need to add foreign key in the child table. you can use something like this:
rails g model Comment post:references
this will add post_id in the comment table.
You could try a non-database backed ActiveModel-like model. For example, Mongoid or Datamapper. Many NoSQL solutions don't require migrations for changes to models.
Try this:
rails g model ModelName --migration=false
Related
I creating an app that needs to be able to create and drop tables on the fly, on create it's pretty simple I use:
rails g model User name:string
but there is no generator for dropping a table.
I want to make it be possible to:
rails g migration DropTableUser
To correct your question, rails g migration User name:string would result in a migration called User not a model, I guess what you meant was rails g model User name:string.
To answer your question, I think it would result in an unnecessary mental effort, especially since something like this already exists in:
rails [d|destroy] model User
If you want to still implement yours, I'd advise that you look at Rails Generators instead for a way to help you out. I guess that would be dependent on creating a migration template etc.
Are migrations instructions that change a model? Will I make several migrations, or will there be one migration per table? For instance, let's say if I want to change "username" to "admin_username". Does this call for a migration? Then, let's say I decide I want to add "age". Do I have to make a new migration, or do I just add it to the aforementioned migration?
You can make the quantity of migrations you want. My advise, try to plan your project and see how your model needs to be in order to avoid migrations. The migration feature is a great way to add, delete, rename fields to your model among other things.
If you need to change the username of the model User then you run rails g migration renameUsernameInUsers and add the necessary code to change the name of that field in you recently created migration file.
If some minutes later you realise that you also need to add a field you can make a new migration with your needs and add a field or add multiple fields in just one migration.
Remember, in order to apply your migrations you need to run rake db:migrate. If you modify the code in your migration files already migrated with this command, it will not have effect in your model. You will need a new migration.
In conclusion, you can(will) make many migrations for a model.
To go further on this topic you can see this official page for migrations in rails.
New to rails and wondering if there is a way to have all the associations you generate from a migration show up in that model. For example, working on a mock AirBNB app. If i were to generate a migration like so (with these models already created)
rails g migration AddListingsToNeighborhood listing:belongs_to
When I run rake db:migrate, my models are still empty. Just wondering if there is a shortcut to have these associations fill the models.
Thank you!
If you have not created the model (or can overwrite it), use
rails g model Neighborhood listing:references
If you have the model and just need to create the appropriate migration:
rails g migration AddListingsToNeighborhoods listing:references
The DB migration will not modify the model.
In these examples, Neighborhood gets the foreign key.
If you want Listing to have the foreign key (and have belongs_to), then you would need to reverse them:
rails g model Listing neighborhood:references
rails g migration AddNeighborhoodToListings neighborhood:references
FWIW, as you grow your apps, you will often be modifying existing models and adding relationships. This means manually adding belongs_to and running the migration.
Is there a way to specify the fields and relationships in the model and run a command to the rails create tables in the database based on the models, and then I can create or remove other fielda, change some relationships and run this command again and rails do update the tables in the database? I thought the migrate did it but after I read about it seems that it only creates the tables once and has no concept of model / db sync that i need.
No you need to create a new migration anytime you need to update the database. Changing some code in the model will not generate a migration.
No, but if you want a simpler way to write your migrations etc, I suggest you read more about the generators :)
For example :
rails generate model user first_name:string last_name:string birth_date:datetime friend:references
will directly generate the migration with the correct fields :)
And if you want to add a field after, you can write it like :
rails generate migration AddPseudoToUsers pseudo:string
And it will be correctly written normally :)
This is the doc
http://guides.rubyonrails.org/migrations.html#creating-a-migration
http://guides.rubyonrails.org/command_line.html#rails-generate
I've been reading about Rails Migrations to help me start building a rails project.
I'm a bit confused on the generation of the files in db/migrate.
The way I've been designing my application is by starting with the models... outlining all of the objects that I'm going to have in the system as best I can. I would like to generate the migration files FROM these models automatically with the rails migration generator.
Yes, I know "creating migrations manually is easy." And I know I could do it manually, but what I don't understand is why the tool is separated from the pre-created models.
Based on my understanding from the article and other migration questions on SO, I can generate a migration like so:
rails generate migration SomeObj field:string some_other_field:integer
What I don't get is why I need to pass in the fields when my model already exists for SomeObj? Couldn't Rails detect it from the some_obj.rb and create the migration from there?
Also, when I have a more complex model, with has_many, belongs_to, and has_to_and_belongs_to_many relationships, it would be really nice if it autocreated the JOIN tables and fields with the correct names (e.g. foreign_obj_id, foreign_obj_ids)
In a previous project I didn't have to deal with migrations because I used Mongo+Mongoid - and collections were automatically generated due to the nature of how Mongo works (collections that doesn't exist get automatically created upon inserting or updating). Now with this Rails app I'm using Postgres (but I'm sure the same thing would happen with MySQL or any other relational database).
Anyway, is there no helper for this kind of thing? Do I have to create all these migrations manually?
You've got this backwards. You need to build your migrations first, and your models second. Migrations advance the state of the database. Your models reflect the current state of the database. There is not a 1-to-1 mapping of models to migrations.
I would like to generate the migration files FROM these models automatically with the rails migration generator.
Can't be done.
You use rails generate migration to generate the migration, which, almost as a side-effect, generates a stub model file. You cannot use your existing model file to generate the model's migration, because the model doesn't contain any information about the actual columns that make up the model. Rails would have to extract and imply all the necessary information from your associations/validations, and even then it would get most of the columns wrong.
Also, when I have a more complex model,... it would be really nice if it autocreated the JOIN tables and fields with the correct names
Again, you can't. You're responsible for defining your database schema, and the way you do so is by building migrations. You can do so manually, or via rails generate, but the process you should be following is building your migrations first, and your models second.
By way of example, here is a complete model, ready for production:
class MyModel < ActiveRecord::Base
end
That model definition might wrap a table that contains 10 columns or 1000 columns; you (and Rails) have absolutely no way of knowing based on the model definition.
Here's another model, which contains at least one column, but again, you have no way of knowing what kind of column:
class MyModel < ActiveRecord::Base
validates :code, presence: true, uniqueness: true
end
Is code a string or a number? Should there be an index on the column? There is absolutely no way of knowing.