Sean
Sean

Reputation: 2577

Table pluralization?

I have 3 tables with the following relationships (tables have been trimmed for simplicity and clarity):

create_table "users", force: :cascade do |t|
  t.string "name", limit: 255, null: false
end

create_table "sleeves", force: :cascade do |t|
  t.integer "user_id", limit: 4
  t.integer "report_id", limit: 4
end

create_table "reports", force: :cascade do |t|
  t.string "name", limit: 255, null: false
end

My models like like this:

class User < ActiveRecord::Base
  has_many :sleeves
end

class Sleeve < ActiveRecord::Base
  belongs_to :user
  has_many :reports
end

class Report < ActiveRecord::Base
  belongs_to :sleeve
end

However, there seems to be a problem with pluralization of some sort in Rails. When I run the following command from console:

user = User.find(1)
user.sleeves

I get the following error:

NameError: uninitialized constant User::Sleefe
from "../gems/ruby-2.2.2/gems/activemodel-4.2.3/lib/active_record/inheritance.rb:158:in 'compute_type'

If I change the user relationship in the model to:

class User < ActiveRecord::Base
  has_one :sleeve
end

Everything works fine (but I only get one report and not the all the reports I need). I suspect the problem is with pluralization of the word Sleeve (as the errors says Sleefe -- which isn't anywhere in code).

Can anyone lead me down the right path for a correction?

Upvotes: 1

Views: 82

Answers (1)

MarsAtomic
MarsAtomic

Reputation: 10673

Plural forms are known as "inflections" in Rails, and they're predefined for you.

Just for the sake of deepening understanding, Rails uses a bunch of regular expressions to determine the proper pluralization to use based on the way the word ends. (you can see them in your_application/lib/active_support/inflections.rb). Regular expressions are an efficient way to match patterns, but they depend on consistency in the target material. English, as a natural language, is irregular and inconsistent, and this is how problems like "sleefe" arise.

In your case, you want to override what appears to be an incorrect inflection by performing some minor surgery on an Inflector file.

Open:

your_application/config/initializers/inflections.rb

Edit inflections.rb to look something like this:

ActiveSupport::Inflector.inflections do |inflect|
  inflect.irregular 'sleeve', 'sleeves'
end

Upvotes: 2

Related Questions