Should About page be named Abouts? - ruby-on-rails

Ruby on Rails naming convention says controllers should be plural, as should associated views. Models are singular.
That makes sense if you have a controller name orders. It is most likely going to have a model named order. However, should the about page be named abouts? That seems odd.
The about page isn't going to have any associated model. Does that make a difference with singular vs plural naming conventions?

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.

By following the Rails convention of naming, you can standardize a lot of things in your project but there can be exceptions.
You can use about instead of abouts if you want, then name the file as about_controller.rb and inside the file, have the class name as: class AboutController. You have to match the class and the file name, then it will work just fine. Rails won't complaint about this.
But again, it depends on the use case. In this use case, I don't think you really need a controller for about page :-) You should be able to handle that in any other multi-purpose/common controller.

You can use rails pluralize method to generate plurals. Use rails console for this.
"about".pluralize

Related

Rails Model method that builds a string of links

I have a method on a model called Photo. I have it finding a selection of things from elsewhere in my app. All I need it to do at the end is to create a string of links that I can then output later on when the method is called on an instance.
My code is:
cars.map { |c| link_to(c.name, c) }.join(" AND ")
But i'm hitting this error:
undefined method `link_to' for #<Photo
Any ideas how to fix this?
link_to is a view helper which means it's only available in Rails views by default because it's a router / request concern.
If you specifically want to use link_to you have to include it or reference it directly.
See this SO answer
include ActionView::Helpers::UrlHelper
...
cars.map { |c| link_to(c.name, c) }.join(" AND ")
There are other ways of getting paths than using link_to that I would recommend you consider:
It's arguable that the Rails team would tell you to use UrlFor as the tip in that link suggests:
Tip: If you need to generate URLs from your models or some other place, then ActionController::UrlFor is what you're looking for. Read on for an introduction. In general, this module should not be included on its own, as it is usually included by url_helpers (as in Rails.application.routes.url_helpers).
UrlFor also allows one to access methods that have been auto-generated from named routes.
class User < ActiveRecord::Base
include Rails.application.routes.url_helpers
def base_uri
# named_route method that uses UrlFor
user_path(self)
end
end
User.find(1).base_uri # => "/users/1"
create your own concern to bring in route helpers via ActionMailer as this article suggests
As you may see if you scroll through other SO questions about including view helpers in models, there is pushback on using router and request -based methods outside of controllers and views because it violates the principles of MVC.
I think your use case can give you some peace of mind about this, but it's worth knowing the water is murky and some people may advise you otherwise.
The traditional Rails wisdom (and what I'm about to give you here) is that models should not be creating HTML. They also shouldn't have methods that return HTML. Creating HTML <a> tags should be done much closer to the user interface: in a view template or maybe in a view helper. One reason is that the particular way the hyperlink should be generated is a concern of the view. (Does it need a nofollow attribute? class attributes? This will change, even from one view to another.) And the model should not have any knowledge of these details.
When you do generate links in the views, then you have access to all the helpers such as link_to.
Instead, as I understand it, a model should be responsible for returning its own data. Maybe in your case that'd be an array of dicts of :label, :url. I.e., pure data that'd be easy to pass to link_to.
Hope that helps!

What is the "_path" method in ruby on rails?

I'm learning RoR, and I'm getting very confused by the "_path" method as it's used in Controllers and Routes. To be more specific, I'm referring to the many different calls that take the syntax "(something)_path". So far as I know, they all seem to either encode or manipulate a URL or link. I'm having a hard time mastering the use of this type of method because I can't figure out what it's core functionality is supposed to be.
For example, I could use the following code to redirect an old URL structure to a page of listed Tweet instances in my config/routes.rb file:
get '/all' => 'tweets#index', as: 'all_tweets'
Only now can I use the following in an .erb file. Notice the "_path" code at the end of the line.
<%= link_to "All Tweets", all_tweets_path %>
I could also use the following code to create a link to an edit page (and another action) in a different .erb file:
<p><%= link_to tweet.user.name, edit_tweet_path(#tweet) %></p>
I've tried reading through my study materials as well as the RoR documentation, but I always end up more lost than when I began. Does anybody know the low-level definition of this "_path" method?
Helper
It's called a route helper, which means that Rails will generate them to help provide you with resource-based routing structures. I'll explain more in a second
--
To explain properly - Rails is just a framework.
Like all software, it is a series of files loaded in a particular order. As such, Rails creates a series of helper methods in the booting process. These "helper" methods can then be used throughout your application to call functionality / information as you require:
The Rails framework provides a large number of helpers for working
with assets, dates, forms, numbers and model objects, to name a few.
These helpers are available to all templates by default.
In addition to using the standard template helpers provided, creating
custom helpers to extract complicated logic or reusable functionality
is strongly encouraged. By default, each controller will include all
helpers. These helpers are only accessible on the controller through
.helpers
The route helpers (which are generated from your config/routes.rb file give you the ability to call routes which are resourceful. These might seem strange to begin with, but once you understand them, will help you inexorably.
--
Resourceful
To give you more clarity - Rails routes are known as resourceful
This means they are constructed around resources. To give you a brief definition of this, you need to appreciate that the resources of your application are the pools of data you can add to, and pull
from.
To explain further, because Rails is object orientated. If you're new, this won't mean very much, but keep it in mind, as when you progress through the language / work, you'll begin to see why this is important.
Object orientated programming puts OBJECTS at the center of the flow. Typically, you'd put logic at the center, but with OOP, it's the objects. This is very important for us, as it means that everything you do in Rails is based around the objects you can create.
As per the MVC principle (which, again, is what Rails is built on), you'll create / invoke your objects from your Models:
This means that if you want to create a series of routes to "CRUD" (Create Read Update Destroy) your objects, Rails is able to create the routes necessary to do that. This is where the resources directives come from inside the routes file:
Hope this helps!
Actually, these paths are generated based on your routes.rb. If you run this command at your project, you would be able to see all available on your app
rake routes
For example, if I declare my resources in routes.rb like this
resources :posts
then I would automatically have following available paths
posts_path
post_path
new_post_path
edit_post_path
If you use some strange abc_path which has not been declared in routes.rb, then you will get errors.
Hope this is helpful, you will definitely need to work more with Rails and then eventually you will understand all of these things :)
you could find definition for these methods in rails repository:
https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/routing/route_set.rb#L127

Creating links using link_to for hierarchical model

Okay, so I am new to Rails and am creating a project management system with the framework. For a couple of my models, views, and controllers I used scaffolding and had no problems. For other parts, I coded all of the parts myself.
So as an overview of my project, at the root of it all you can have many projects. Within all of these projects you can create multiple to-do lists. Within each to-do list, you can have multiple tasks. This is what I meant by "hierarchical" in the title.
I just created my lists page, and when I go to the URL directly in my browser (ex: http://localhost:3000/projects/3/lists/20/tasks/1) the task is displayed correctly. However, I do not know how to format my link that is in one of my to-do list views (the tasks are usually shown below the to-do list but now I want them to show on their own view).
Here is the code I currently have:
<%= link_to "#{task.description}", project_list_tasks_url(#list.id,task.id) %>
I know that the link_to "#{task.description}" is correct because I tried using it with a static URL (Google or something), but project_list_tasks_url(#list.id,task.id) is where I'm having trouble.
Can anybody help me out? I can provide as much code as you'd like from my to-do list or task controllers and views.
A couple of tips to help make routing less confusing. It can be a bit unnerving to get used to.
Routing Rule #1
Always check the output of rake routes to be sure how to call your various routing methods. You might think you know how your routes will play out by looking at routes.rb but you won't know until you look at the compiled routes table.
In your case you're expecting a route with the format:
/projects/:project_id/lists/:list_id/tasks/:id
Be sure that's the case. If it is, your call should look like:
project_list_task_path(#project, #list, task)
Note that the arguments here are :project_id, :list_id and :id, so all three are required in this case. Any in brackets in the path specification can be ignored, like :format usually is.
Routing Rule #2
Use the _path methods unless you strictly require the full URL. They're shorter and the output is easier to read and debug. They also don't inadvertently flip the URL in the browser and cause session problems if you don't properly differentiate between www.mysite.com and site.com.
Routing Rule #3
Don't forget there's a huge difference between #project and #project.id when it's supplied to a routing path method.
The router will always call the to_param method if it's available and this can be over-ridden in your model to produce pretty or friendly URLs. id is for your database and your database alone. to_param is for routing but you shouldn't be calling it manually unless you're doing something exceptionally irregular.
You generally should not nest resources more than one level deep, but putting that aside, the link_to format should be:
link_to task.description, project_list_task_path(#project, #list, task)
i.e. project_link_tasks_url should be project_link_task_url, and you have to pass the #project as the first argument (I'm assuming that your project is named #project). I've switched _url to _path so you can just pass the objects themselves as arguments rather than their ids.
See the documentation on creating paths and URLs from objects for details.

hyperlink in ruby on rails

This is something probably trivial but i can't quite find my way round it:
How do i add a hyperlink from one ruby-file.html.erb to another please?
Ruby uses something called routes. You can create named routes for some operations or you can use resource routes (autogenerated CRUD per resource).
For example if you have route for a model called Car, then calling
link_to "Edit my car", edit_car_path(#car)
in your view will generate a link.
remember that your are linking to a controller action in model/view/controller and not to pages

Singular or plural controller and helper names in Rails

Is there any disadvantage to using singular names for controllers and helpers? Nothing seems to rely on this. It even seems helpers don't have to make the same choice about singular vs. plural as their corresponding controllers, at least according to my limited experimentation. Is that true?
Definitely plural.
With restful routing and a singular controller
Controller:
dog_controller.rb
Routes:
map.resources :dogs # => blows up
map.resources :dog # is ok, but...
dogs_path # => blows up
dog_path # => ok
Using a plural controller
Controller:
dogs_controller.rb
Routes:
map.resources :dogs
dogs_path # => ok
dog_path # => ok
rails generate controller --help has plural examples:
Example:
`rails generate controller CreditCards open debit credit close`
CreditCards controller with URLs like /credit_cards/debit.
Controller: app/controllers/credit_cards_controller.rb
Test: test/controllers/credit_cards_controller_test.rb
Views: app/views/credit_cards/debit.html.erb [...]
Helper: app/helpers/credit_cards_helper.rb
Using plural names for controllers is just a convention.
Plural names usually sound more natural (especially for controllers that are tied directly to a specific model: User -> Users, etc.), but you can use whatever you want.
As for helpers, all helpers are available for all controllers by default, so technically, how you name your helpers doesn't matter at all. It's just another convention to keep a controller's helper functions in a helper with the same name as the controller.
A Model is singular because it references a single object like User. A controller is plural because it is the controls (methods) for the collection of Users. How one names the routes is all up to that individual developer. I've never had a user complain that a URL for a web request is singular or plural. The end result to maintain a common convention for current and future contributors while serving quality page displays or the API requests for the end users.
You have a very complete explanation in the Rails guides:
http://edgeguides.rubyonrails.org/routing.html#resource-routing-the-rails-default
It is the Rails convention that one controller handles one model, whether one or more instances of that model can exist during runtime. However, you can have a Rails application where (some of) the controllers (and the associated views) are not associated with any particular model, but rather handle a more complex set of functionality. In this case, the automatic pluralization doesn't make any sense.
The Rails application I'm currently working on fits into this category, and it's simply an irritation to me that Rails expects that the identifiers I define as a singular in one place are then used in their plural forms in other places. For example, I might want to define something like this in config/routes.rb:
resource :dashboard, :only => [:show]
and then I want a controller DashboardController to display summary information about certain aspects of the application, gathering information from more than one database table. So here, Dashboard does not refer to any model of the application, and it would be just weird to have the controller's name be DashboardsController.
I found a good solution to the irritation of automatic pluralization in this answer. In short, edit file config/initializers/inflections.rb and add the words you don't want to be automatically pluralized to this definition:
ActiveSupport::Inflector.inflections do |inflect|
inflect.uncountable %w( dashboard foo bar baz )
end
If the controller is a resource then it must be plural...
For example
Controller
articles_controller.rb
Model
article.rb
But you can use singular controller names when you do not have corresponding models like
welcome_controller.rb
The naming convention of controllers in Rails favors pluralization of the last word in the controller's name, although it is not strictly required (e.g. ApplicationController).
For example, ClientsController is preferable to ClientController, SiteAdminsController is preferable to SiteAdminController or SitesAdminsController, and so on.
Following this convention will allow you to use the default route generators (e.g. resources, etc) without needing to qualify each :path or :controller, and will keep URL and path helpers' usage consistent throughout your application.
Ref: Controller Naming Convention-Rails Doc
I feel better when I use singular for Controller name
Using plurals just sounds better, and then if you have a controller that handles a singular resourse, ie user, then you can still name the url /user.
With helpers there is often no need to have a helper for every controller, and often there will be helper methods you can use ascorss multiple controllers and rather litter them all through your application helper you could put them in custom helpers instead like eg layout_helper or any other well named file.

Resources