So i've looked around and don't see a built in way to handle words that are named weirdly in the english language.
I have a Quiz model, which means that i have an index action of \quizes.
resources 'quizes', only: ['index', 'new', 'show']
I would like to be able to do things like
quizes_path #Note this one works
quiz_path(:id) #this does not
I have to do quize_path(:id)
Here is the rake routes, notice that the path names are quize instead of quiz.
quizes GET /quizes(.:format) quizes#index
new_quize GET /quizes/new(.:format) quizes#new
quize GET /quizes/:id(.:format) quizes#show
This is more for learning. I know i could just manually specify the singular resources and be done.
The ultimate question, is there a way to specify this in resources so that it knows that the singluar resources should remove 'es' instead of just 's'
EDIT
Here is the correct inflector based on the resources. Thanks!
ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.singular /^(quiz)es/i, '\1'
end
Use quizzes instead of quizes in your route definition:
resources :quizzes
Then the singular routes are:
new_quiz GET /quizzes/new(.:format) quizzes#new
edit_quiz GET /quizzes/:id/edit(.:format) quizzes#edit
quiz GET /quizzes/:id(.:format) quizzes#show
As #Anand's answer says you need to spell "quizzes" correctly in this instance. To answer your general question you're looking for inflections in the file config/initializers/inflections.rb. This has been asked before: Ruby on Rails Inflection Issue and Ruby on Rails: How do you explicitly define plural names and singular names in Rails? as examples.
Related
I am working on Rails 4.1.0. And i have generated leaves_controller and Leave model in my application.
But the application generated routes for leaves as like new_leafe, edit_leaf etc.
Actually I want the singularize string of Leave as Leave only, like new_leave_path, edit_leave_path.
If any idea to singularize class name in Rails, please share.
If it's only the routes you wish to change, you could use the as: option:
#config/routes.rb
resources :leaves, as: "leave"
--
Alternatively, if you'd like to set the term within Rails, you may wish to use an Inflector like this:
How do I override rails naming conventions?
#config/initializers/inflectors.rb
# Add new inflection rules using the following format
ActiveSupport::Inflector.inflections do |inflect|
inflect.irregular 'leave', 'leaves'
end
I have a category with a subcategory and the subcategory has posts. I'd like to link it as following:
/categoryname/subcategoryname/post_id/postname
I've tried doing so by putting this in my routes:
resources :categories do
resources :subcategories do
resources :posts
end
end
But any time I'd like to create a link for my subcategories (/categoryname/subcategory/) via link_to(subcat.name, category_subcategory_path)
I get:
No route matches {:controller=>"subcategories", :action=>"show"} missing required keys: [:category_id, :id]
How would I approach this to get the desired link setup?
Thanks in advance,
Slugs
Firstly, if you're looking to use slugged routes, you'll be best looking at gems including friendly_id or slugalicious -- basically allows you to manage "slugs" for your models -- saving titles or other attributes in URL encoded format
Paths
Secondly, I think you'll resolve your issue by providing values, rather than using the path helper. I would do this:
link_to subcat.name, category_subcategory_path(category.id , subcat.id)
When you use a path helper, it only cares about which params you send. The path helper you're using requires you to set the category_id and subcategory_id params -- which you should pass to the path helper as demonstrated above
This will create the path using id's - if you'd like to use slugs, you'll need to use one of the aforementioned gems (friendly_id is recommended) to set up the slugs in your app
I am little bit confused in using rails route. I need some suggestion about customizing my url.
This is my current url
http://localhost:3000/posts/product/41?product_id=2
and
http://localhost:3000/posts/product/41?model_id=24&product_id=2
This is my link
<%= link_to product_model.name, controller: :posts,action: :product,product_id: params[:product_id],model_id: product_model.id
Logically product should come first in url. But why model prefers first here.
And i need my url something like this
http://localhost:3000/posts/product/41/mobile
and
http://localhost:3000/posts/product/41/mobile/nokia
Since i am not familiar with rails route i didn't write any special coding in my route
Here is the simple route exist
resources :posts
Ok your question here actually contains two different problems, so i will give suggestions to both.
1. Nested resources
Your first problem is to use "nested routes". Rails guide has a long and good article about routes and how to write and use them, including nested routes. You can check it out here: http://guides.rubyonrails.org/routing.html#nested-resources.
However in your situation would the solution look something like this:
resources :category do
resources :sub_category do
resources :products do
resources :models
end
end
end
You can now greate links like this
<%= link_to product_model.name, category_sub_category_product_model_path(#category, #sub_category, #product, product_model) %>
You can see that i have removed posts, see 3. Refactor design to see why. If you really want this as a action on posts, should you however do something like this (but would recommend this!):
get "posts/product/:category_id/:subcategory_id/:product_id/:model_id", to "posts#product", as: :posts_product
This would be used like this in your views:
<%= link_to product_model.name, posts_product_path(#category, #sub_category, #product, product_model) %>
2. Pretty URL's
Your second problem is to use model names instead of id's in your urls. The simpels solution for this is having a unique attribute on your model that you can use instead of id, and then just add a to_param method. Fx for product could we do something like this:
class Product < ActiveRecord::Base
def to_param
name
end
end
Ryan Bates have made a good screencast about this: http://railscasts.com/episodes/63-model-name-in-url-revised. If you want something more flexible should you use the gem Friendly Id. And again does Ryan comes to the rescue with another great RailsCast: http://railscasts.com/episodes/314-pretty-urls-with-friendlyid.
3. Change design
Ok well so this is just my opinion, feel free to ignore it. But their is some bad practices and signs in your examples, so let me just quickly go through what i think you should improve on.
Restful actions
You should, when possible always avoid creating controller actions that is not restful (simply put is the base actions index, show, new, create, edit, update and destroy the only restful actions). In your example does this mean that the product action of the posts controller should be changed to something restful. Why not move it to the product model controller and call it "show"?
Deeply nested resources
You should avoid nesting your routes to deeply. Is it really important to show both the category, the sub category, the product AND the model in your url? Maybe that's how your models are associated internally in your application but why should the user know this? If you don't have a list of subcategories at "/posts/product" and a list of products at "posts/product/41" is there no reason to have so long a route. A rule of thumb is "nest no deeper then two levels", ie. ":category/:sub_category". Further more does short routes mean better SEO.
As i said, feel free to ignore these suggestions, your application would work without these changes. However changing these things would greatly help you structure you code, and keep your codebase clean and maintainable. These rules and principles is not something i have just conjured out of nothing, but very accepted principles in the Rails community. You can google each of these principles or patterns and see a lot of articles and posts on why it's a good idea to follow them, especially when you work with Rails.
Resources
Rails Routing from the Outside In — Ruby on Rails Guides
norman/friendly_id - Github
#314 Pretty URLs with FriendlyId - RailsCasts
#63 Model Name in URL (revised) - RailsCasts
Take a look at the friendly-id gem
There's a great RailsCast about it
Add this to your model inmodel.rb
def to_param
name
end
and then add
#model = Model.find_by_name(params[:id]) to your show method, then you can get the url as you mentioned above.
PS: You Should have name field for Model table in your schema.
I think you are looking for nested routes. Please refer this link http://guides.rubyonrails.org/routing.html#nested-resources
and use to_param method in the model if you want to display model_name instead of id as explained by #Ajay Kumar
def to_param
name
end
where name is the model attribute for that specific model.
Why not a namespace?
namespace :posts do
resources :products
end
This should do I think..
Namespace does not include restful ids into the scope..
I have a CRUD resource defined in my routes.rb file: resource :user.
I'm adding a new controller method for the user called search_places, which is performed on the user to find other users with the same places. I'm adding a route it.
Right now, I have:
post '/user/search_place', which isn't very DRY. I'm new to Rails and I was reading the Rails routing documentation and figured that I could possibly use
resource :user do
collection do
post 'search_place'
end
end
Is this considered good practice? I know this works (it passes my rspec route test), but is that how its best done?
Thank you,
When you add second don't need of first.
Add this:
resources :user do
collection do
post 'search_place'
end
end
Remove this:
resources :user
That makes DRY :)
Suggestion: Resources name should be defined in plural if u follow rails convention. (i.e) resources :users
I am using Ruby on Rails 3.0.9 and I would like to build a controller name from a class name as well as possible following RoR naming conventions. For example, if I have the Articles::Comment class I would like to retrieve the articles/comments string.
Maybe it exists a RoR method created by developers to handle internally these conventions, but I don't know that.
How can I retrieve the controller name as in the example above?
You're looking for the underscore method. More info here.
"Articles::Comment".underscore
Or, if you've got the controller class itself, it would be like this:
Articles::Comment.name.underscore
EDIT
As of routes, they are built one piece at a time, even when you namespace them. When you do something like this:
map.resources :articles do |articles|
articles.resources :comments
end
What rails is going to do is, first:
"articles". classify # which yields "Article" then rails is going to append "Controller" to it
Then it's going to get "comments" and do the same, but this one is going to be routed under "/articles". Rails does not namespace internal resources, so, the controller has to be CommentsController, not Articles::CommentsController.
Only then you clearly namespace something, Rails is going to namespace your classes:
map.namespace :admin do |admin|
admin.resources :articles # will require controller "Admin::ArticlesController"
end
I hope it's clearer now.