Method pluralize seems not working - ruby-on-rails

I need to generate a migration that creates a table called creditcardquotas, but rails generate a table called credit_card_quota exactly like the name of the model.
I tried with the method pluralize
helper.pluralize(2, 'quota')
=> "2 quota"
class CreateCreditCardQuota < ActiveRecord::Migration
def change
create_table :credit_card_quota do |t|
t.integer :credit_card_id
t.integer :quotes
t.integer :interest
t.timestamps
end
end
end
How do I tell Rails migration that I want that the table called credit_card_quotas?

Create a file in config/initializers/. Name that file inflections.rb and add this content in it.
Before adding you get:
helper.pluralize(2, 'quota')
=> "2 quota"
Add the inflection:
ActiveSupport::Inflector.inflections do |inflect|
inflect.plural 'quota', 'quotas'
end
After that:
helper.pluralize(2, 'quota')
=> "2 quotas"
You can add any kind of valid or invalid pluralizations in this file...
Run the migrations after having applied this configuration change.

In my recent experience, it seems like rails/active record does not know how to pluralize the word "quota", or that it thinks that the plural of the word "quota" is "quota". I just tried to create a new migration for a "quotas" table that was paired with a Quota class in quota.rb. In rails console, when trying to use this model, I saw this warning:
Quota(Table doesn't exist)
But when I updated my Quota class to be Quotas and renamed the file, I was able to use the quotas table in the db. My eventual solution was to change the db table name from quotas to quota and use the Quota class for my model.

Related

Show time when articles were edited/created - rails

Is it possible to add the time when a certain article was edited or created through the administration framework, using rails?
By adding the time, I mean when some user reads that article on the website, he can also read the last time it was edited or created.
I know I can add it manually, but I want to make it automatic.
Thank you!
By default, every Rails generated model includes timestamps called created_at and updated_at which correspond to when the record was initially created (added to the DB) and last updated.
As long as your migration to create the model has the following line, then the timestamp functionality will be enabled
class CreateProducts < ActiveRecord::Migration[5.0]
def change
create_table :products do |t|
# ...
t.timestamps
end
end
end
Resources:
http://api.rubyonrails.org/classes/ActiveRecord/Timestamp.html
http://guides.rubyonrails.org/active_record_migrations.html

What is the correct way to generate multi-word reference fields in rails

rails generate model product name:string twoWord:string twoWordRef:references
produces the following migration file
class CreateProducts < ActiveRecord::Migration
def change
create_table :products do |t|
t.string :name
t.string :twoWord
t.references :twoWordRef, index: true
t.timestamps null: false
end
add_foreign_key :products, :twoWordRefs
end
end
I thought that field names were supposed to be snake case, not camel case, yet rails generate model is producing camel case field names in the migration file. I think I am following the examples on my generate command.
I am also finding issues later on when I try to update via reference where rails assumes the foreign key is in snake case and can't find my foreign key in the table.
What am I doing wrong? Thanks
Rails automatically generate the database tables in snake case. For example if your model is TestModel corresponding table in database will be test_models. However same is not the case for attributes.
Do this instead:
rails generate model product name:string two_word:string two_word_ref:references
Update
This is completely out of scope for what OP asked, but I thought sharing this might be helpful if you are starting Rails. Rails uses a few conventions when naming models and tables (like singular name for model and plural for table). For this it uses ActiveSupport::Inflector module.
The Inflector transforms words from singular to plural, class names to
table names, modularized class names to ones without, and class names
to foreign keys. The default inflections for pluralization,
singularization, and uncountable words are kept in inflections.rb.
You can use its classify and tableize methods to validate corresponding names. Eg:
"test_models".classify
# => "TestModel"
"TestModel".tableize
# => "test_models"

Single Table Inheritance not working in Rails 4 app - ActiveRecord::SubclassNotFound: The single-table inheritance mechanism failed

I have a new Rails 4 app where I created a few models in the STI configuration.
The main model is called Order and it inherits from ActiveRecord::Base. This is how it looks like:
class Order < ActiveRecord::Base
TYPES = %w(remote local)
scope :remotes, -> { where(type: 'remote') }
scope :locals, -> { where(type: 'local') }
end
The other two models are within a folder in models/orders and they're called Remote and Local and they both inherit from Order
The orders migration file looks like this:
def change
create_table :orders do |t|
t.string :source_url, null: false
t.string :final_url, null: false
t.string :type
t.string :category
t.timestamps
end
end
I also made sure I was including the models/orders dir into Rails, by doing:
config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**}')]
Now, when I log into the console with an emptied DB and run Order.all everything is fine and I get an empty relation object. But after I create the first Remote object and try running Order.all again I get the following error:
>> Order.all
Order Load (1.0ms) SELECT "orders".* FROM "orders"
ActiveRecord::SubclassNotFound: The single-table inheritance mechanism failed to locate
the subclass: 'Remote'. This error is raised because the column 'type' is reserved
for storing the class in case of inheritance. Please rename this column if you didn't
intend it to be used for storing the inheritance class or overwrite
Order.inheritance_column to use another column for that information.
What is going on here? What have I done wrong?
Thanks in advance.
In order to debug this, I'd simply and see what I learn from one of two experiments...
First, even just temporarily, move the subclasses out of the Orders folder. It may be that you have them nested in a Module, or that rails expects them to be based on the name, so the 'type' column doesn't match what you think it should.
second, I'd try creating one of the subclasses from the command line, persisting it, and seeing what ActiveRecord puts in that type column and see if it matches what you're expecting.
I suspect this has something to do with the subfolder under models and Rails' inability to find the class as the type is specifying it.
Column name 'type' is restricted in ActiveRecord. try renaming the column name to something else or if you can't try this:
self.inheritance_column = :_type_disabled
I had this same issue when I used type as a column name, maybe try renaming your column name to something else?

Renaming original migration file in Rails after doing the rename_table_migration

I happened to create a Query model in Rails and recently found out that this is one of the reserved words now..
I renamed the table using a new migration file and renamed all the files that were created (name of new model - Plot)
Question: is it OK to rename the original migration file (20111228212521_create_queries.rb) to 20111228212521_create_plots.rb)
and everything inside the old file:
class CreateQueries < ActiveRecord::Migration
def change
create_table :queries do |t|
t.string :name
t.text :content
t.timestamps
end
end
end
to
class CreatePlots < ActiveRecord::Migration
def change
create_table :plots do |t|
t.string :name
t.text :content
t.timestamps
end
end
end
??
I just don't want too many migration files and also worried that there may be some errors when I switch to production..
You can change the migration file name, but you have to perform a few steps:
rake db:rollback to the point that queries table is rolled back.
Now change the name of migration file, also the contents.
Change the name of any Model that may use the table.
rake db:migrate
The short answer is to just make another migration file.
Migration files are meant to keep track of each and every change to the database. So, you're encouraged to make small one-off changes in a separate file. I can't speak for your situation, but in my situation, when I make a mistake like this, I simply create a new migration file and don't check the old migration file into source control. This way the errant changes are only on my local db and don't get into prod/dev/staging.
Aside from rolling back, and especially useful for when you need to rename a migration from early on in production you can now in Rails 4 create a new migration to rename it.
$rails generate migration RenamesFooBarr
and then in the method of the new migration add
rename_table :old_migration_name, :new_migration name
like this:
class RenamesFooBar < ActiveRecord::Migration
def change
rename_table :old_foo_bar_name, :new_foo_bar_name
end
end
This will effectively take care of all the indexes as well in the up and down since ActiveRecord recognizes the rename_table
source: http://api.rubyonrails.org/classes/ActiveRecord/Migration.html
Simply, do like this
Rollback the migration for that queries. i.e rake db:rollback
Change migration file, class name and the content of it.
Finally, Migrate the database. i.e rake db:migrate

Rails 3 ActiveRecord Table Name Issue

I'm on Windows XP...
Ruby 1.9.2
Rails 3.0.9
MS SQL Server 2005
I'm using tiny_tds + activerecord-sqlserver-adapter
In my database I have table named t4.
I have created a model like this: rails generate model t4
Here is my simple model t4.rb:
class T4 < ActiveRecord::Base
end
Here is migration file 20111013125957_create_t4s.rb:
class CreateT4s < ActiveRecord::Migration
def self.up
create_table :t4s do |t|
t.timestamps
end
end
def self.down
drop_table :t4s
end
end
I have schema.rb:
...
create_table "t4", :force => true do |t|
t.string "title", :limit => 50
end
...
Problem:
When I try T4.select("title").where(["id = 3"]) I get error message:
ActiveRecord::StatementInvalid: TinyTds::Error: Invalid object name 't4s'.: SELECT title FROM [t4s] WHERE (id = 3)
P.S.:
I have another some tables named Adddocs and Eclaims.
There are not problems with queries to them.
I guess that problem is that T4.select("title").where(["id = 3"]) maps to SELECT title FROM [t4s] WHERE (id = 3) (T4 to t4s).
Why? I don't know
But when I edited file config/initializers/inflections.rb like this:
ActiveSupport::Inflector.inflections do |inflect|
inflect.irregular 't4', 't4'
end
Everything works! But it's not suitable solution (bad tone i think) :(((
By convention, if you create a model named album, rails will create a table called albums.
To override this (which isn't usually done) and use a custom defined table name you can use set_table_name method like this in your model:
class Album < ActiveRecord::Base
self.table_name="album" * define here whatever table name you have
end
When you create a new model it is the singular of the object your storing, whereas when it then generates the table, it uses the plural as there are multiple stored within the table. Example...
If you create a model named user, you'll end up with app/models/user.rb but the table it makes will be called users.
If you don't like that you have a few options...
You can override the inflections as you've done, however you should only do this if Rails is getting the pluralization wrong, rather than forcing it to use a certain word.
You can override the table name using the set_table_name method in the model file, providing it with a parameter of what your table name actually is.
You could disable the whole pluralized table names with config.active_record.pluralize_table_names = false in your config/application.rb file, however I strongly recommend you don't do this.
Ultimately I would suggest using more descriptive table names which can be pluralized over ones that can't. T4 as a model and table name don't explain to me what's stored within, where as Post does.

Resources