I have created a new table including a column "note". The default is varchar(255) I believe but I wish to have this column be a text area vs. a field and to allow more data. I imagine that I would make this change in ActiveRecord::Migration file but I am curious as to the format. Do I simply change the varchar(255) to varchar(1000) for example? (if so what is the format?
def self.up
create_table :notes do |t|
t.string :note :varchar(1000)
end
Is that the right format? Furthermore, how do I get the entry field to be multiple rows. Sorry if this is easy stuff but I am new to programming and RoR. Thanks.
The correct format would be
t.string :note, :limit => 1000
make sure you are using a version of MySQL(or whichever database) which supports varchars longer than 256 characters.
if you want to use a large text block it would be
t.text :note
See http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html for more information
You can change the length with the limit option as so...
def self.up
change_column :notes, :note, :string, :limit => 1000
end
You can simply use the 'text' type instead of 'string'.
def self.up
create_table :notes do |t|
t.text :note
end
end
Using the 'text' type will result in database column of type TEXT. Varchar is usually limited to a maximum length of 255 (in MySQL, other RDBMSs have similar limits).
If you use Rails' form helpers, a textarea will be output for this field (because it is of type 'text'). textarea is the form element that accepts multi-line input.
Edit: If you've already migrated the create_table, you can create a new migration to change the column type:
def self.up
change_column :notes, :note, :text
end
Since I had a lot of data already stored I used
self.up
change_column :notes, :note, :text, :limit => nil
end
If I left off the :limit => nil option then the column type would change from varchar to text, but it still had a max length of 255 characters.
Related
I know I can do this in a change migration and have it be reversible:
add_column :widgets, :color, :string
remove_column :widgets, :flavor, :string
But strangely, change_table->remove does not work like this. Instead of params (name, type), it takes a list of column names. (If you attempt to append a type parameter, it gets interpreted as a column name.)
change_table(:widgets) do |t|
t.column :color, :string
t.remove :flavor, :string # <-- nope! It tries to remove a column named "string"
end
When you try that, you get this error:
remove_columns is only reversible if given a type.
Is there another call I am be overlooking? It seems weird that change_table could be missing such a fundamental use case, but I don't see any calls in the docs that can do it.
While experimenting, I tried this and it works:
change_table(:widgets) do |t|
t.column :color, :string
t.remove :flavor, type: :string
#^^^^^
end
So I guess that's the answer.
ActiveRecord::ConnectionAdapters::Table is generally just a thin wrapper around ActiveRecord::ConnectionAdapters::SchemaStatements - in this case remove_columns which takes a list of columns and an options hash.
type and other column options can be passed to make migration reversible.
remove_columns(:suppliers, :qualification, :experience, type: :string, null: false)
remove really just provides the first argument - which is the table.
I made an error and generated my Item model with string field instead of integer.
Here is my migration
class CreateItems < ActiveRecord::Migration
def change
create_table :items do |t|
t.string :name
t.string :url
t.text :photo
t.string :price
t.timestamps null: false
end
end
end
But right now I want to sort my items by price field and rails sorts it bad way because it is stored as string.
For example it thinks that price 9 is bigger than 1111111111.
Right now I order them like this:
#items=Item.where(:category_id => #active_category_id).order(:price)
What do I do?
Fix the column type. You can do it with the following migration:
class ChangePriceTypeInItems < ActiveRecord::Migration
def change
change_column :items, :price, :integer
end
end
The data in price column will be preserved if the string contained represents an integer value.
By the way, I think a price needs to be a decimal not an integer. But, you choose.
try this:
#items = Item.where(category_id: #active_category_id).sort { |a, b| b.price.to_i <=> a.price.to_i }
this gets all with your category id and then compares the prices as integers instead of strings. It should give you the order you're looking for.
I am trying to setup a model based on a pre-built model that has the following code in the migration:
def change
create_table :friendships do |t|
t.string :user_id, :friend_user_id
t.string :status
end
end
I get the t.string :status part where a column is being created which will use a string. I don't understand the t.string :user_id, :friend_user_id part where there are two attributes on the same line.
In the first line, two columns are being created named as user_id and friend_user_id having string data type. In the second line there is another column being created named status having string data type. So in migrations you can write all column names in one line which have the same data type. i.e. The migration can be written like this.
def change
create_table :friendships do |t|
t.string :user_id, :friend_user_id, :status
end
end
This is a join table to show relationship. Actually user_id and friend_user_id all refer to id in users table.
Say my id is 10 and yours is 11. I regard you as a "good" friend. So in this table there is a record: 10, 11, "good". But you think me as a normal friend, so one more record: 11, 10, "normal"
This is simply a declaration of two columns with similar attributes in the same line. It is similar to
t.string :user_id
t.string :friend_user_id
You can find the documentation for that in here (look for "Short-hand examples")
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
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.