Ruby on Rails: How to migrate changes after adding validation on models? - ruby-on-rails

I'm new to Ruby on Rails and I'm currently working on models. I have added a new validation to pre created attribute.
This is the validation that I have added.
validates_presence_of :services, :message => 'This field is non-editable'
Do I have to migrate the changes after adding validation? If yes then how?
Any kind of help would be greatly appreciated.

Records already in your database won't be affected. But it you edit a previous record, you won't be able to store it without passing the validation.
You've 3 options:
On edit/update, force new field value (default in your case)
Create a migration to set default value on the column.
Create a migration to update each row with a correct value (not really a good option in my mind)

Related

Save Not working after new field added to already generated scaffold in rails?

Let's say that I add one more field in my model. Then i made changes in my _form page.But when i try to save I am not being able to save the latest field.
if you are using rails version above 4, you have to add that field to strong params.
See the last private method:
saying params.require(:foo).permit(:bar, :baz, :new_field)

Adding default values to rails 4 migrations and updating existing records

Recently I realized that none of my database columns have default values. If an object is instantiated and then saved, it might have nil values for any fields that aren't filled out.
I can make it so that I explicitly initialize these values, but then I've got some places where two controllers are creating the same object, but I didn't think of moving that code into a separate module.
I can also choose to update my migrations to specify default values, which seems cleaner.
I've decided to go with migrations. It is not a good idea to edit old migrations, so I'm creating a new migration and specifying that I want to change certain columns.
Looking at how I should change columns, I have determined that I will use this
def change
change_column :products, :size, :default => 0
end
Will this modify existing records that currently have nil set for those records?
No, it will not update your old records.
You should NEVER change old migrations, it is a relief you noticed that.
I suggest you to create a rake task that will update all the fields OR you can do it directly on console like the code below.
Product.update_all({ size: 0 }, { size: nil })

Ruby on Rails: how to migrate changes made on models?

In a Rails application, how can I migrate the changes I make in models? For instance, I know that if I create a model with command "rails g model Person name:string", a migration will be created as well. However, if after this step I go to the created model "Person" and add a new attribute, will this new attribute be automatically added to a migration for later persistance in database?
Or am I looking at this from the wrong side, and an attribute should be added to a migration, and then added to a model?
Regards
You can't really "add" an attribute to a model, you do that by creating the migration file and running it -- Rails figures out what attributes a model has based on what columns are in the database. However, you do need to add a line to the model to whitelist the attribute if you want to be able to update it via mass assignment. That's why you'll often see a line like this in activerecord models:
attr_accessible :name
But that's optional and not essential to adding the attribute.
To actually add the new attribute to your model, first create a migration with:
rails g migration AddAddressToPerson address:string
That will create the migration file in the db/migration/ directory. (The form “AddXXXToYYY” and “RemoveXXXFromYYY” are understood by rails to mean "add (or remove) a new column to the model XXX", see the documentation for details). In this case I've added an attribute named address which is a string, but you could change that to whatever you want it to be.
Then to actually update the database, you need to run the migration with rake:
rake db:migrate
Finally, if you want to allow mass assignment on that attribute, add the attribute to your list of arguments to attr_accessible:
attr_accessible :name, :address
That should do it.
If you are adding the new attribute with attr_accessor, you will not need to do anything with migrations, but your changes will not be stored in the database.
If you do want to persist your changes, you will need to add the attribute to your model using a migration. You can just create a text file, with the proper structure, migrations are nothing fancy, but it is a lot easier to generate on like this rails generate migration AddLastNameFieldToUsers. The contents of such a file might be adjusted to look like this:
class AddLastNameFieldToUsers< ActiveRecord::Migration
def change
add_column :users, :last_name, :string
end
end
You don't need to add attributes directly to the model. Rails (actually ActiveRecord) infers it automatically. For the list of attributes for the model class, AR looks for a table with a plural form of the model's name (if model is Order, then it will look for attributes in the orders table). It is part of the design feature called CoC - Convention over Configuration.
So you if you have to add an attribute, you have to create a migration to add that field into the column as mentioned in other answers.

Adding validations to existing model in Rails

I would like to add a :presence and :uniqueness validation to a model in Rails. I'm using MongoDB and the Mongoid gem.
I have a model that is already in use and have existing records in the DB. I'd like to add a new :field and then add validations for :presence and :uniqueness for the field.
I know that by default, any existing records will simply add the :field and the result will be null unless I specify a :default.
My question is, since I want this new :field to be unique, will this cause an error for the existing records in the DB that will be null? Will I lose these records or does Rails just apply the validations to the new records?
Rails/AciveRecord will not ignore or delete your old records...
Validations work as follows: they are only used/checked when you try to write stuff to the database, e.g. when you create a new record or when you update a record. So in your case you will get validation errors when you try to update an old record without adding the new required fields.
I suggest that you try to clean up your database when adding the new fields (meaning adding sensible defaults to old records for the new required fields).

Rails Association Validations: The field, or the _id field?

One of the messier practices I have in Rails development is juggling validations of associated fields between validating the actual object (eg: validates_presence_of :related_object) and validating on the id column for that association (eg: validates_presence_of :related_object_id).
I figure I should probably start being a little more consistent with this, and before I commit to anything, I'm wondering if there's any advantage of either method over the other? I can't think of anything, but then I've been known to overlook stuff before. So, does it make any difference? Is there a convention re: what most developers do that I should abide by?
Any suggestions appreciated.
This question comes up every so often.
In most cases you will want to validate the presence of the actual associated object, not just verify that an id (which could well be invalid) has been set.
Validating association_id will also prevent you from creating the object with a new association record and saving both together.
Of course you have to check the presence of :object_id. If you check the presence of :object then this object will be fetched from your DB and then will be checked via simple blank?. I guess you won't be happy with additional DB hit.

Resources