Ruby on Rails Plural (Controller) and Singular (Model) Convention - Explanation

Ruby on Rails plural (controller) and singular (model) convention - explanation

Ruby on Rails follow linguistic convention. That means a model represents a single user,
whereas a database table consists of many users.

Why Controller names are plural but application_controller is itself a singular

Rails is full of conventions and plural names for controllers is simply one of those conventions. It is so Rails can locate the appropriate controller when you put resources :books in your routes.rb

You can override the convention and specify the controller explicitly, resources :books, controller: "library". In this case, Rails will look for LibraryController.

With ApplicationController, you don't call it directly and Rails doesn't need to do this lookup and so it can be named whatever. You can rename it, for example.

how/why does rails decide to name some files with a plural or singular naming convention?

Model

By convention A Model is singular because it represents a single object like a Post, a User etc.. but database table names are plural because they represent a collection of objects.

In your case model name is HighScore and rails will look for class definition class HighScore < ActiveRecord::Base inside the file high_score.rb. You can perform all validations and model related task inside the class.

Controller

A controller is plural because it represent model objects. Although using plural names for controllers is just a convention. For example Users controller will represent objects from User model.

In your case above scaffold will generate a controller HighScores and rails will look for class definition class HighScoresController < ApplicationController inside the file high_scores_controller.rb

In your controller you can find some restful actions such as index, show,edit, update, destroy . The purpose of index action is to list all highscores so you define a instance variable @highscores which will store all highscores from database table like @high_scores = HighScore.all which is then passed to the index view. Similarly the purpose of show action is to display a single highscore. In your show action you can define a instance variable @highscore which will store a specific high score form db table like @high_score = HighScore.find(params[:id]) and ten pass it to show view.

In MVC frameworks (such as Ruby on Rails), does usually Model spell as singular and controller and view spell as plural?

Generally, Rails has a very specific format for naming models, controllers, and views that is not necessarily the only way to accomplish the task. The Rails tradition is:

  • Models are in singular form (ie. Story)
  • Controllers are in plural form (ie. Stories)
  • Views are sorted by folder according to the name of the controller (ie. stories/show.html.erb)

Django appears to use a similar convention with:

  • Models are singular
  • "views" (which are basically controllers) are not necessarily tied to a particular model
  • "templates" do not folow a particular convention, although several exist.

Since CakePHP (especially) seems to follow behind Rails's every move, I would expect that it follows the same convention.

As for the exception, I would imagine that it has to do with URL routing. Before Rails 2.3 (I think), Rails routes were automatically set based on the controller name (now the router has far greater flexibility). While they could be changed, most people chose not to mess about in the router. I would much prefer to visit yourwebsite.com/user/ to visit my home page on the website when logged in than yourwebsite.com/users/22.

Remember: conventions exist for a reason, but there are times when conventions are broken reasonably. Keep "convention of configuration" only when it makes sense.

Intelligent plural always intelligent?

Rails knows a lot of plurals. It can handle "city," for example:

1.9.2p318 :001 > "city".pluralize
=> "cities"
1.9.2p318 :002 > "cities".singular
=> "city"

However, you may find plurals it doesn't know, and won't be learning. See the documentation for ActiveSupport::Inflector

The Rails core team has stated patches for the inflections library
will not be accepted in order to avoid breaking legacy applications
which may be relying on errant inflections. If you discover an
incorrect inflection and require it for your application, you’ll need
to correct it yourself (explained below).

How do you correct it yourself? In config/initializers/inflections.rb. For example:

ActiveSupport::Inflector.inflections do |inflect|
inflect.plural /^(.*)(l)ens$/i, '\1\2enses'
end

See again the docs for ActiveSupport::Inflector for more on how to teach rails new inflections.

Is it the rails way to use singular or plural controller names?

You can use either. If you are defining your routes using resource(s) then it's best to use plural controller names, because that is the default:

resources :articles
resource :articles

But it is possible to specify other controller names as well:

resources :articles, :controller => 'article'
resource :article, :controller => 'article'

What are drawbacks of naming controllers in singular form is Rails?

Well, the simplest reason would be that anyone else who works on that project will probably refer to it in the plural while working on the code, then have to realize "oh, they decided to not follow convention in that one controller" after an unspecified time period of "WTF?" while they try to figure out what they are doing wrong. Also semantically, your controller is a controller of ALL the Portfolios in the Portfolio table.

Code-wise you will have issues with routes. You will have to craft a bunch of non-standard routes because http://my_app/portfolios goes to the index action of the controller by default. You then show a particular portfolio with http://my_app/portfolios/1 which will show you the portfolio with the id of 1. So be prepared to create and maintain a host of custom routes in your config/routes.rb file. You see similar problems with things that have names that are the same whether plural or singular like equipment where you can have one piece of equipment or many pieces of equipment. See this: rails link path and routing error when model singular and plural name are the same (e.g. equipment, species). Not only is it making your routes wonky, it is causing conflicts in methods like portfolio_path or portfolio_url.

Rails Conventions pluralisations

This question is fairly old but I stumbled across it looking for a way to handle the word staff(as in employees at a company) correctly.

The reason it pluralises with the 's' is because the plural of staff(as in wizards staff) is staffs(staves is also valid). So if you needed a table with different kinds of (wizards)staffs it is valid. However the plural of staff(as in people at a company) is staff.

Rails assumes that you are referring to the wizards staff in this instance. With words with only one meaning that don't have a separate plural, this works correctly:

[1] pry(main)> "sheep".pluralize == "sheep" 
=> true

How to fix this?

config/initializers/inflections.rb

ActiveSupport::Inflector.inflections do |inflect|
inflect.plural "staff", "staff"
end

This will tell rails that the plural of staff is staff and the naming conventions will be respected.

rails generate scaffold staff name:string description:text active:boolean

      invoke  active_record
create db/migrate/20220518125452_create_staff.rb
create app/models/staff.rb
invoke test_unit
create test/unit/staff_test.rb
create test/fixtures/staff.yml
invoke resource_route
route resources :staff
invoke inherited_resources_controller
create app/controllers/staff_controller.rb
invoke erb
create app/views/staff
create app/views/staff/index.html.erb
create app/views/staff/edit.html.erb
create app/views/staff/show.html.erb
create app/views/staff/new.html.erb
create app/views/staff/_form.html.erb
invoke test_unit
create test/functional/staff_controller_test.rb
invoke helper
create app/helpers/staff_helper.rb
invoke test_unit
create test/unit/helpers/staff_helper_test.rb
invoke assets
invoke coffee
create app/assets/javascripts/staff.js.coffee
invoke scss
create app/assets/stylesheets/staff.css.scss
invoke scss
identical app/assets/stylesheets/scaffolds.css.scss

The migration:

create_table :staff do |t|
t.string :name
t.text :description
t.boolean :active

t.timestamps
end

Should About page be named Abouts?

For static content pages (eg. 'about us', 'terms and conditions', 'privacy policy', etc.) I typically stray away from typical REST conventions.

I would create a single PagesController and have one action for each page (eg. def about_us; end. Each action would just render the view with the content for that page.



Related Topics



Leave a reply



Submit