resource routes without member id - ruby-on-rails

I develop a Rails application and I added simple route:
Name::Application.routes.draw do
resource :categories
end
The problem is that there is no member id in the generated URLs:
$ rake routes
categories POST /categories(.:format) categories#create
new_categories GET /categories/new(.:format) categories#new
edit_categories GET /categories/edit(.:format) categories#edit
GET /categories(.:format) categories#show
PUT /categories(.:format) categories#update
DELETE /categories(.:format) categories#destroy
I use Rails 3.2.3. I don't use ActiveRecord in the application (but I don't know if it is relevant). I have a model Category and CategoriesController.
What might be the problem?

You forgot to add s in the end:
resources :categories
resources and resource are different things: resources and resource.

Related

Creating a link to a rails route

Rails 5.2.3
In my routes.rb, I have:
get '/books/:author', to: 'books#index'
get '/books/:author/show', to: 'books#show'
post '/books/:author/create', to: 'books#create'
Which, when running rake: routes, gives me:
GET /books/:author(.:format) books#index
GET /books/:author/show(.:format) books#show
POST /books/:author(.:format) books#create
When a route helper is not provided by rake: routes, can I assume that when I create a link to it in a view, I can use use the model name, like: books_path or books_url? something like:
= link_to books_path(:author => #author), :method => :post
I tried it, but I am getting an error message:
undefined method books_path
So, I am either doing something wrong in routes.rb, or I am not referencing it correctly?
You are creating an unnamed route. I think what you want in your particular situation is:
resources :books, only: [:index, :show, :create], param: :author
That will give:
Prefix Verb URI Pattern Controller#Action
books GET /books(.:format) books#index
POST /books(.:format) books#create
book GET /books/:author(.:format) books#show
This does not seem RESTful to me though. I think what you really want is a nested resource between books and authors. Check out the Rails guides on routing for more information: https://guides.rubyonrails.org/routing.html
Just to pile on, I suggest you use nested routes:
resources :authors do
resources :books, shallow: true
end
resources :books, only: [:index, :create, :new]
Which will give you (amongst other things):
author_books GET /authors/:author_id/books(.:format) books#index
POST /authors/:author_id/books(.:format) books#create
new_author_book GET /authors/:author_id/books/new(.:format) books#new
edit_book GET /books/:id/edit(.:format) books#edit
book GET /books/:id(.:format) books#show
PATCH /books/:id(.:format) books#update
PUT /books/:id(.:format) books#update
DELETE /books/:id(.:format) books#destroy
authors GET /authors(.:format) authors#index
POST /authors(.:format) authors#create
new_author GET /authors/new(.:format) authors#new
edit_author GET /authors/:id/edit(.:format) authors#edit
author GET /authors/:id(.:format) authors#show
PATCH /authors/:id(.:format) authors#update
PUT /authors/:id(.:format) authors#update
DELETE /authors/:id(.:format) authors#destroy
books GET /books(.:format) books#index
POST /books(.:format) books#create
new_book GET /books/new(.:format) books#new
That ought to give you everything you need to manage authors and books.
I don't get how post '/books/:author/create', to: 'books#create' gives you POST /books/:author(.:format) books#create.
If you want to name your custom routes add the name with the :as option: get 'something', to: 'controller#action', as: 'something' to get "something_path" as a valid helper.
Note that you are going away from RESTful routes, if you want rails to do the things it usually do (like the named routes helpers) you should stick with it's conventions: https://guides.rubyonrails.org/routing.html
It's books_author_path, most likely.
Just remember what you're doing is not good practice at all. (It's actually beyond terrible for a coc framework like Ruby).
First of all, nested new routes are fine but nested create routes are generally considered bad.
Second, why is books/author_id/create creating a book?
It should be authors/author_id/books/new to books/create
Go into your console and type in "rails routes" and it'll tell you what all the helper urls are

undefined method `category_documentations_path' in Rails. My routes have comments instead of documentations

I try do to a nested form, and when I load the form (/categories/show.html.haml), I get this error:
NoMethodError in Categories#show
Showing /home/cederic/rails/mordus/app/views/categories/show.html.haml where line #6 raised:
undefined method `category_documentations_path' for #<#<Class:0x00007fead8742870>:0x00007fead8881038>
Did you mean? category_comments_path
config/routes.rb
Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
resources :categories do
resources :documentations
end
get 'pages/accueil'
root 'pages#accueil'
end
The output of "rails routes" command:
refix Verb URI Pattern Controller#Action
category_comments GET /categories/:category_id/comments(.:format) comments#index
POST /categories/:category_id/comments(.:format) comments#create
new_category_comment GET /categories/:category_id/comments/new(.:format) comments#new
edit_category_comment GET /categories/:category_id/comments/:id/edit(.:format) comments#edit
category_comment GET /categories/:category_id/comments/:id(.:format) comments#show
PATCH /categories/:category_id/comments/:id(.:format) comments#update
PUT /categories/:category_id/comments/:id(.:format) comments#update
DELETE /categories/:category_id/comments/:id(.:format) comments#destroy
categories GET /categories(.:format) categories#index
POST /categories(.:format) categories#create
new_category GET /categories/new(.:format) categories#new
edit_category GET /categories/:id/edit(.:format) categories#edit
category GET /categories/:id(.:format) categories#show
PATCH /categories/:id(.:format) categories#update
PUT /categories/:id(.:format) categories#update
DELETE /categories/:id(.:format) categories#destroy
pages_home GET /pages/home(.:format) pages#home
root GET / pages#home
Found it. It was a strange bug.. doesn't know if it from my text editor or whatever, but I copy the content of routes.rb, delete it, create a new routes.rb file and pasted the content, and now it works.
These resource routes aren't matching up with the output of 'rails routes' - have you changed the routes.rb file since you ran 'rails routes'? If your routes.rb looks like you say above, 'rails routes' should return something along the lines of the following (with 'documentations' instead of 'comments'):
category_documentations GET /categories/:category_id/documentations(.:format) comments#index
category_documentations POST /categories/:category_id/documentations(.:format) comments#create
...

Rails Routes Wrong Prefix

I'm getting a strange error when renaming the resourcce "like" to "love"
In routes.rb I've changed:
resources :likes
resources :recipes do
member do
get :likes
end
end
to
resources :loves
resources :recipes do
member do
get :loves
end
end
and rake:routes says
loves GET /loves(.:format) loves#index
POST /loves(.:format) loves#create
new_lofe GET /loves/new(.:format) loves#new
edit_lofe GET /loves/:id/edit(.:format) loves#edit
lofe GET /loves/:id(.:format) loves#show
PATCH /loves/:id(.:format) loves#update
PUT /loves/:id(.:format) loves#update
DELETE /loves/:id(.:format) loves#destroy
loves_recipe GET /recipes/:id/loves(.:format) recipes#loves
recipes GET /recipes(.:format) recipes#index
POST /recipes(.:format) recipes#create
new_recipe GET /recipes/new(.:format) recipes#new
edit_recipe GET /recipes/:id/edit(.:format) recipes#edit
recipe GET /recipes/:id(.:format) recipes#show
PATCH /recipes/:id(.:format) recipes#update
PUT /recipes/:id(.:format) recipes#update
DELETE /recipes/:id(.:format) recipes#destroy
and ofcourse i get an error
uninitialized constant User::Lofe
but where comes the prefix "Lofe"? looks a bit strange for me
This is due to the active support pluralization features in rails.
To solve your issue:
in config/initializers/inflections.rb add the following:
ActiveSupport::Inflector.inflections do |inflect|
inflect.uncountable %w(Loves)
end
After running $ rake:routes I get:
Prefix Verb URI Pattern Controller#Action
loves_index GET /loves(.:format) loves#index
POST /loves(.:format) loves#create
new_loves GET /loves/new(.:format) loves#new
edit_loves GET /loves/:id/edit(.:format) loves#edit
loves GET /loves/:id(.:format) loves#show
PATCH /loves/:id(.:format) loves#update
PUT /loves/:id(.:format) loves#update
DELETE /loves/:id(.:format) loves#destroy

Change the scope of routes to 'admin' for specific actions

I have a category model and in my routes.rb, I have
resources :categories
which generates the following set of routes.
categories_path GET /categories(.:format) categories#index
POST /categories(.:format) categories#create
new_category_path GET /categories/new(.:format) categories#new
edit_category_path GET /categories/:id/edit(.:format) categories#edit
category_path GET /categories/:id(.:format) categories#show
PATCH /categories/:id(.:format) categories#update
PUT /categories/:id(.:format) categories#update
DELETE /categories/:id(.:format) categories#destroy
Now, what I need is except for all GET routes, I want the rest of the routes to be under '/admin' scope. So that operations like create, edit and delete are accessed at admin/categories/:id/edit etc.
Is there an easy way to mention this scope?
You may wish to organize groups of controllers under a namespace. Most commonly, you might group a number of administrative controllers under an admin namespace. You would place these controllers under the app/controllers/admin directory, and you can group them together in your router:
namespace "admin" do
resources :posts, :comments
end
This will create a number of routes for each of the posts and comments controller. For Admin::PostsController, Rails will create:
GET /admin/posts
GET /admin/posts/new
POST /admin/posts
GET /admin/posts/1
GET /admin/posts/1/edit
PATCH/PUT /admin/posts/1
DELETE /admin/posts/1
check the rest of it through the apidock documentation
I think you can define route of categories twice.
resources :categories, :only => :index
resources :categories, :except => :index, :path => 'admin/categories'

How to use plural names for nested resources?

I am using Ruby on Rails v3.2.2 and I would like to use plural names for nested resources. That is, in my config/routes.rb I have (note: "category" and "article" are sample resources):
resources :categories do
resources :articles do
collection do
get 'one'
post 'two'
put 'three'
end
member do
get 'four'
post 'five'
put 'six'
end
end
end
The above statements generates the following:
$ rake routes
one_category_articles GET /categories/:category_id/articles/one(.:format) articles#one
two_category_articles POST /categories/:category_id/articles/two(.:format) articles#two
three_category_articles PUT /categories/:category_id/articles/three(.:format) articles#three
four_category_article GET /categories/:category_id/articles/:id/four(.:format) articles#four
five_category_article POST /categories/:category_id/articles/:id/five(.:format) articles#five
six_category_article PUT /categories/:category_id/articles/:id/six(.:format) articles#six
category_articles GET /categories/:category_id/articles(.:format) articles#index
POST /categories/:category_id/articles(.:format) articles#create
new_category_article GET /categories/:category_id/articles/new(.:format) articles#new
edit_category_article GET /categories/:category_id/articles/:id/edit(.:format) articles#edit
category_article GET /categories/:category_id/articles/:id(.:format) articles#show
PUT /categories/:category_id/articles/:id(.:format) articles#update
DELETE /categories/:category_id/articles/:id(.:format) articles#destroy
categories GET /categories(.:format) categories#index
POST /categories(.:format) categories#create
new_category GET /categories/new(.:format) categories#new
edit_category GET /categories/:id/edit(.:format) categories#edit
category GET /categories/:id(.:format) categories#show
PUT /categories/:id(.:format) categories#update
DELETE /categories/:id(.:format) categories#destroy
I would like to change statements in my config/routes.rb so to generate following routers with plural names only for the category_article "part" (that is, I would like to use categories_article/categories_articles respectively instead of category_article/category_articles):
$ rake routes
# Note: I marked changes from the previous outputting with '=>'.
=> one_categories_articles GET /categories/:category_id/articles/one(.:format) articles#one
=> two_categories_articles POST /categories/:category_id/articles/two(.:format) articles#two
=> three_categories_articles PUT /categories/:category_id/articles/three(.:format) articles#three
=> four_categories_article GET /categories/:category_id/articles/:id/four(.:format) articles#four
=> five_categories_article POST /categories/:category_id/articles/:id/five(.:format) articles#five
=> six_categories_article PUT /categories/:category_id/articles/:id/six(.:format) articles#six
=> categories_articles GET /categories/:category_id/articles(.:format) articles#index
POST /categories/:category_id/articles(.:format) articles#create
new_category_article GET /categories/:category_id/articles/new(.:format) articles#new
edit_category_article GET /categories/:category_id/articles/:id/edit(.:format) articles#edit
category_article GET /categories/:category_id/articles/:id(.:format) articles#show
PUT /categories/:category_id/articles/:id(.:format) articles#update
DELETE /categories/:category_id/articles/:id(.:format) articles#destroy
categories GET /categories(.:format) categories#index
POST /categories(.:format) categories#create
new_category GET /categories/new(.:format) categories#new
edit_category GET /categories/:id/edit(.:format) categories#edit
category GET /categories/:id(.:format) categories#show
PUT /categories/:id(.:format) categories#update
DELETE /categories/:id(.:format)
If you aren't satisfied with the provided helpers then you can use the magic:
<%= link_to 'One', [:one, #category, Article] %>
# /categories/123/articles/one
<%= link_to 'Four', [:four, #category, #article] %>
# /categories/123/articles/456/four
<%= link_to 'Edit the article', [:edit, #category, #article] %>
# /categories/123/articles/456/edit
<%= link_to 'All articles for the category', [#category, Article] %>
# /categories/123/articles
The very same approach can be used to specify the :url option for the form_for helper.
I hope you got the idea!
P.S. Note the using of a class (like Article) to specify that you want to see all records and using of a model instance (like #article) to say that you are about to see one article.

Resources