Force max length for string in PostgreSQL - ruby-on-rails

I am using heroku for a RoR application and am trying to manually set the length of a string column and am having trouble.
I tried making a migration along the lines of
change_column :posts, :content, :string, :length => 10000
I assumed this would work but no such luck, anyone have some pointers?
Thanks!

The length limit option in Rails migrations is called :limit:
change_column :posts, :content, :string, :limit => 10000
If you are finding yourself changing VARCHAR length limits a lot, you might want to read #depesz's blog post on VARCHAR vs TEXT.

Related

I'm not sure I'm applying the Rails change migration properly

I'm building a Rails application that allows a user to catalogue tires by inputting values into the UI. When I created the tire class , I made it as
class CreateArticles < ActiveRecord::Migration[5.0]
def change
create_table :tires do |t|
t.decimal :price
...
end
end
When I ran the program I realized that I'd neglected to specify the precision and scale of the decimal attribute. This resulted in the program being unable to accept non-integer values and displaying all values appended by .0 Because I was so much farther along on the program, I decided to write another migration to just change price to a float by writing the following migration:
class ChangeTiresToFloat < ActiveRecord::Migration[5.0]
def change
change_column :tires, :price, :float
end
After running db:migrate, there is no change in the behavior of the program. Should this not have made it so that the UI could accept float values?
Edit: Before resorting to making the price column a float value, I did try to fix the decimal value by adding the missing attributes with this migration:
class MoneyDecimalFix < ActiveRecord::Migration[5.0]
def change
change_column :tires, :price, :decimal, :precision => 8, :scale => 2
end
end
After rolling forward the migration, the program's behavior still did not change.
Although it is possible to use a change_column migration to edit the price value to include the decimal attribute's specifications, because the create_table is a reversible migration, it is advisable to instead roll the migration back and manually implement the change to ultimately read
t.decimal :price, :precision => 8, :scale => 2
then roll the migration forward again.
It is however worth noting that, although having the price column correctly defined in the migration is an essential step, it alone did not fix the issue of the form not accepting decimal values.
The error was ultimately in my Views. Within Rails, the number_field tag, on its own, will not accept decimal values, it must be 'combined' with a text_field tag in order to do so as such:
<%= f.number_field :price, class: :text_field, step: :any %>

Rails text field size limit error - text(255)

I have a rails DB and I noticed some save errors when putting a lot of text into text areas.
I checked and for some reason they've been created as either text or varchar but with limits of 255, here's the viewer from a DB client.
I tried the below migration to see if it would change to text with no limit however it's not had any effect:
change_column :investors, :notes, :text
change_column :investors, :has_property_notes, :text
change_column :investors, :jv_partner_notes, :text
Other text fields don't seem to have this problem. Any suggestions would be greatly appreciated!
Thanks
Nick
Use limit nil for stubborn databases. Also you should put this in a new migration.
change_column :investors, :notes, :text, :limit => nil
change_column :investors, :has_property_notes, :text, :limit => nil
change_column :investors, :jv_partner_notes, :text, :limit => nil

RAILS: DB MIGRATION: resetting id column to auto_increment

When I created the table users, the resulting table had a column called id, defined as an integer.
I tried to modify it to bigint, unsigned as follows:
change_column :users, :id, :integer, :limit => 8, :unsigned => true
Which did change it to bigint, but it was no longer an auto-increment column (though it was still identified as the primary index, and it was not set to unsigned (even though rails told me that the migration executed fine)
I then tried doing:
change_column :users, :id, :integer, :limit => 8, :unsigned => true, :null => false, :auto_increment => true
Rails said that the migration executed fine, but nothing changed.
I could try something like:
change_column :users, :id, :primary_index
but that would put me right where I started
I could also try an "execute" statement with MySQL code, but I want to keep the migration file "clean". Has anyone run into this issue?
As an aside, I was also trying to set the default to NULL on another column, researched it here (and Google), with no success.
EDIT:
It seems as if there is no way to edit the column "id" after it is created as part of table creation through a generic migration. The only way to do this is through an "execute" statement with MySQL syntax.
Try creating and running this migration:
class ChangeColumnUserIdToAutoIncrement < ActiveRecord::Migration
def self.up
execute "ALTER TABLE users modify COLUMN id int(8) AUTO_INCREMENT"
end
def self.down
execute "ALTER TABLE users modify COLUMN id int(8)"
end
end
Rails is taking care for you the ID field of all the tables you're creating and it's hidden from your migrations and even from the schema.rb file.
So I would advice you to take a step back and think: Why would you want to mess with it? Are you sure that's really needed?
EDIT: This answer seems to be exactly what you're looking for.
Regarding "setting default to NULL", again, why would you do that? All the columns are defaulting to NULL anyway. However, if that's not the case you could do that in a migration:
change_table :users do |t|
t.string :description, :default => nil
end
Hope that answers your question.

Set a default value in a decimal column

How do you set a default value in a decimal column in Rails? I've tried both the following, using Rails 3 and Postgresql, but after each one the console tells me the default values are still nil. If I set the value from the console, there's no problem, but it doesn't seem to work in the migration.
#Attempt 1
add_column :providers, :commission, :decimal, :precision=>6,:scale=>4,:default=>0.1
and
#Attempt 2
add_column :providers, :commission, :decimal, :precision=>6,:scale=>4,:default=>BigDecimal("0.1")
Many thanks for your help!
It turns out I also need to set :null=>false
The following code worked:
add_column :providers, :commission, :decimal, :precision=>6,:scale=>4,:default=>0.1, :null => false

varchar Migration question for Ruby on Rails

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.

Resources