I need to add a new column to my users table in the database. I want the type of the column to be set. The column represents the users gender. There should be two options to the set. One form Male "m" and the other for Female "f".
But I haven't found any documentation for adding a column with the set type.
How can I do this?
What db is used? mysql? If you're want to use SET datatype, you'll have to do it manually, as rails doesn't support it. However, I'd do just
t.string :gender, :limit => 1
for the sake of convenience.
In your Users model, you should add the following line to require M/F answers.
validates_inclusion_of :gender, :in => %w( m f M F)
I think you want to add the gender column with a default datatype (correct me if I'm wrong), If so there would be the step
here I'm assuming 'M' is for male and "F" is for female (you can use integers also if you wish)
create a migration
ruby script/generate migration add_gender_column_to_users
This will create a migration for you and as the name implies it will add a gender column to your users table
in your migrations self.up action add this
add_column :users, :gender, :string, :default => 'm'
here it says we are adding a gender column of string type and its default values is 'm'
and add this to self.down events
remove_column :users, :gender
so your final migration will look something like this
class AddGenderColumnToUsers < ActiveRecord::Migration
def self.up
add_column :users, :gender, :string, :default => 'm'
end
def self.down
remove_column :users, :gender
end
end
and do a
rake db:migrate
thats it, hope this helps
Related
The rails globalize gem docs are great, but I can't find a solution, what I have to do, when I want to rename a column.
Last Year I did that, to add the translation fields.
def up
remove_column :news, :name
News.add_translation_fields! name: :string
end
def down
add_column :news, :name, :string, default: nil
remove_column :news_translations, :name
end
Now I want to rename the column "name" to "title", without loosing my data and translations. How do I have to write the migration file?
Alter the column on the news translations table directly:
def change
rename_column :news_translations, :name, :title
end
class AddRatingToBooks < ActiveRecord::Migration
def up
add_column :books, :rating, :integer
end
def down
remove_column :books, :rating
end
I have the following snippet of code in my db/migrate/, I'm trying to add ratings to my books table, where it would be in a range from 0-100, but I'm not sure how to add that here, all i could find was querying with ranges. I'm sure it's simple I'm just not there yet.
You don't need to specify the range of integer values in your migration file. The migration file is simply used to add the database column to store the rating. This is not the place to add validations.
You should use your Book model to specify a validation that ensures your ratings fall within a certain range. Something like this:
class Book < ActiveRecord::Base
validates :rating, :inclusion => { :in => 0..100 }
end
I would highly recommend reading the Rails guides on both migrations and validations.
Probably I'm too late with the answer. But it's possible to define validation on db level with Migration Validators project: https://github.com/vprokopchuk256/mv-core
As example, in your migration:
def change
change_table :books do |t|
t.integer :rating, inclusion: 0..100
end
end
and then in your model:
class Book < ActiveRecord::Base
enforce_migration_validations
end
As result your validation will be defined both in db ( as statement inside trigger or check constraint, depending on your db) and on your model
SQL ( PostgreSQL ):
=# insert into books(rating) values(10);
INSERT 0 1
=# insert into books(rating) values(200);
ERROR: new row for relation "books" violates check constraint "chk_mv_books_rating"
Rails console:
Book.new(title: 10).valid?
=> true
Book.new(title: 200).valid?
=> false
In this SO article I can see how to add a default value to a certain table:
Add a default value to a column through a migration
change_column :shops, :currency_id, :integer, :default => 1
I have another table currencies that has an ID and also a ISO_Name. I want the system to use EUR as default value. But it's possible that this has ID 5 or ID 1 or ...
So my question: How can I define a default value that is based on the result of a query? For example Currency.find_by_iso_code('EUR').id
As you have iso_name field in the currencies, you can achieve it by the following code.
change_column :shops, :currency_id, :integer, :default => Currency.find_by_iso_name('EUR').id
How about:
class SetDefaultCurrencyForShops < ActiveRecord::Migration
def up
currency = Currency.find_by_iso_code('EUR')
if currency
change_column :shops, :currency_id, :integer, :default => currency.id
end
end
end
The Ruby on Rails convention for database table and field names is snake_case and not CamelCase. However, I have an existing database being used by a PHP application. I would like to write a Rails application that interacts with this database. Is there an easy, "Rails way" to interact with a database using CamelCase database table and field names?
The short answer is yes but it's not always easier than migrating the old database to a new database. If you want both applications to be able to use the same database though then it is probably the quickest approach up front.
You can override the table and foreign key fields by doing the following:
set_table_name "camelCaseName"
set_primary_key "cameCaseIdName"
You can alias all the field names if necessary as well:
alias "camelCaseFieldName", "field_name"
All of the AR relationships can set the primary key field as well.
has_many :comments, :foreign_key_id => "commentCamelCaseID"
It's more work than normal but it is possible.
Sure. In your model, just define your table like so:
class FooBar < ActiveRecord::Base
self.table_name = "FooBar"
end
the same holds true for field names, which you can define in your migration or schema. You can assign any name you like. It takes a bit more work unless you want to override the default mechanic, but it's still possible:
create_table "products", :force => true do |t|
t.column "shop_id", :integer
t.column "creator_id", :integer
t.column "name", :string, :default => "Untitled"
t.column "value", :string, :default => "Untitled"
t.column "created_at", :datetime
t.column "updated_at", :datetime
end
For more info, see Table Definitions
for the datbases tables name you could use set_table_name
class Dog < ActiveRecord::Base
set_table_name 'dog'
end
for the field you could override your accessor .
hope be usefull . bye
Let's say I create a table in a Rails migration, specifying to omit the ID column:
create_table :categories_posts, :id => false do |t|
t.column :category_id, :integer, :null => false
t.column :post_id, :integer, :null => false
end
Later I decide I want to add an ID column as a primary key so I create a new migration:
class ChangeCategoriesToRichJoin < ActiveRecord::Migration
def self.up
add_column :categories_posts, :id, :primary_key
end
def self.down
remove_column :categories_posts, :id
end
end
But when I look at the table after I migrate, it looks like this:
category_id
post_id
id
The id column is in the last position in the table, whereas normally an id column would be first.
Is there a way to change the ChangeCategoriesToRichJoin migration to insist on the id column being created BEFORE the category_id column in the table?
Or do I need to drop the table and add the column in the "create table" definition?
Use :after => :another_column_name, e.g.:
change_table :users do |t|
t.integer :like_count, :default => 0, :after => :view_count
end
I haven't been able to put the columns in order, myself, but with Rails you can rollback, alter the old migration file to add the new columns in the order you want, then re-migrate up the old migration including the new field. It's not exactly ideal, but the ability to migrate and rollback easily, it can work if you're OCD enough to require column order. :P
I am not an expert, but I've read a lot of Rails documentation (and very recently) and can't recall finding a solution for this.