How to use plural names for nested resources? - ruby-on-rails

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.

Related

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
...

undefined method `comments_path' which I can't find in the code files

I am getting the error below (NoMethodError) while trying to add a new comment to an article , the problem is that it refers to undefined method `comments_path' which I can't find in the code files
Please help
Note:
I have tried to search about this error , but results I found were not relevant also the problem is the error is pointing to something I can't find.
The error is shown below:
NoMethodError in Comments#new
Showing /home/abc/my_ruby_projects/myblog3/app/views/comments/_form.html.erb where line #1 raised:
undefined method `comments_path' for #<#:0x007fb57888bf28>
Did you mean? font_path
Extracted source (around line #1):
<%= form_with model: #comment do |form| %>
<% if comment.errors.any? %>
<div id="error_explanation">
<....>
<ul>
Trace of template inclusion: app/views/comments/new.html.erb
Rails.root: /home/abc/.../myblog3
I have defined nested routes for articles & comments as shown below:
resources :articles do
resources :comments
end
my routes seems correct , as shown below:
Prefix Verb URI Pattern Controller#Action
rails_admin /admin RailsAdmin::Engine
article_comments GET /articles/:article_id/comments(.:format) comments#index
POST /articles/:article_id/comments(.:format) comments#create
new_article_comment GET /articles/:article_id/comments/new(.:format) comments#new
edit_article_comment GET /articles/:article_id/comments/:id/edit(.:format) comments#edit
article_comment GET /articles/:article_id/comments/:id(.:format) comments#show
PATCH /articles/:article_id/comments/:id(.:format) comments#update
PUT /articles/:article_id/comments/:id(.:format) comments#update
DELETE /articles/:article_id/comments/:id(.:format) comments#destroy
articles GET /articles(.:format) articles#index
POST /articles(.:format) articles#create
new_article GET /articles/new(.:format) articles#new
edit_article GET /articles/:id/edit(.:format) articles#edit
article GET /articles/:id(.:format) articles#show
PATCH /articles/:id(.:format) articles#update
PUT /articles/:id(.:format) articles#update
DELETE /articles/:id(.:format) articles#destroy
Your form is looking for a route to which it can post the comment updates.
Your routes config likely needs something like
resources :comments
A command line call to list routes will now show you this comments_path it's looking for
rake routes
And then you'll need a CommentsController with an update method/action to handle the postback.
class CommentsController
def edit
end
def update
# save data
end
end
If you're trying to add comments to an article I imagine you have a nested resource where an Article has many comments. Now your /config/routes.rb would have an entry like:
resources :articles do
resources :comments
end
and assuming there is accept_nested_attributes in your /models.article.rb model.
Now in your view usually your form should look something similar to:
<%= form_for [#article, #comment] do |f| %>
When routing I find it useful using the rails routes command, but once they grow too much instead of piping the output to grep I'd rather use the gem sextant in development.

Route to action of controller

Previous i used:
data: {autocomplete_source: categories_path} %>
To point to the action index in categories controller.All worked fine!
Now i created an new action in categories controller
def search
#categories = Category.order(:name).where("name like ?", "%#{params[:term]}%")
render json: #categories.map(&:name)
end
And tried to point to that action:
data: {autocomplete_source: search_categories_path} %>
But i get the error:
undefined local variable or method `search_categories_path' for #<#<Class:0x51844c8>:0x5375820>
What did i wrong? Thanks!
My routes:
products GET /products(.:format) products#index
POST /products(.:format) products#create
new_product GET /products/new(.:format) products#new
edit_product GET /products/:id/edit(.:format) products#edit
product GET /products/:id(.:format) products#show
PUT /products/:id(.:format) products#update
DELETE /products/:id(.:format) products#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
Routes:
Autorails::Application.routes.draw do
resources :products
resources :categories do
collection do
:search
end
end
Check rake routes if that route really exists under that name.
For more information see http://guides.rubyonrails.org/routing.html#path-and-url-helpers
You should have something like this in your routes.rb:
resources :categories do
collection do
get :search
end
end
You should do something like this
resources :categories do
collection do
get :search
end
end

Drop Down Menus and passing the selected value in between views Ruby on Rails

I have a drop down menu of all the objects that are part of one model using this code:
<h2>Upload Grades Using "New Grades"</h2>
<%= collection_select :course, :course_id, Course.all, :id,
:name, :prompt => "Select a Course:" %>
<%= link_to 'New Grade', new_grade_path(:course => :course ) %>
In this case my model is Course. How do I access the selection of the user and then pass it to the new.html.erb view. It is to my knowledge that I use the controller to retrieve the value using something like
#course = params[:course][:course_id]
Then in my view, I can display the name of the course with
<%= #course.name %>
inside of the new.html.erb.
And then, if the course has an association like A course has_many students then I can retrieve and display a list of all the students doing something like
#students = #course.students
But, my thinking here is wrong because my code doesn't work. Can someone point out where I'm going wrong here? I've been at this for hours...
Update - included config/routes.rb and rake routes
MygradesSr::Application.routes.draw do
resources :evals
resources :teams
resources :categories
resources :grades
resources :categories
resources :tasks
resources :students
resources :courses
post 'grades/upload_grade'
post 'students/upload_student'
root :to => "home#index"
end
Rake routes:
evals GET /evals(.:format) evals#index
POST /evals(.:format) evals#create
new_eval GET /evals/new(.:format) evals#new
edit_eval GET /evals/:id/edit(.:format) evals#edit
eval GET /evals/:id(.:format) evals#show
PUT /evals/:id(.:format) evals#update
DELETE /evals/:id(.:format) evals#destroy
teams GET /teams(.:format) teams#index
POST /teams(.:format) teams#create
new_team GET /teams/new(.:format) teams#new
edit_team GET /teams/:id/edit(.:format) teams#edit
team GET /teams/:id(.:format) teams#show
PUT /teams/:id(.:format) teams#update
DELETE /teams/:id(.:format) teams#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
grades GET /grades(.:format) grades#index
POST /grades(.:format) grades#create
new_grade GET /grades/new(.:format) grades#new
edit_grade GET /grades/:id/edit(.:format) grades#edit
grade GET /grades/:id(.:format) grades#show
PUT /grades/:id(.:format) grades#update
DELETE /grades/:id(.:format) grades#destroy
GET /categories(.:format) categories#index
POST /categories(.:format) categories#create
GET /categories/new(.:format) categories#new
GET /categories/:id/edit(.:format) categories#edit
GET /categories/:id(.:format) categories#show
PUT /categories/:id(.:format) categories#update
DELETE /categories/:id(.:format) categories#destroy
tasks GET /tasks(.:format) tasks#index
POST /tasks(.:format) tasks#create
new_task GET /tasks/new(.:format) tasks#new
edit_task GET /tasks/:id/edit(.:format) tasks#edit
task GET /tasks/:id(.:format) tasks#show
PUT /tasks/:id(.:format) tasks#update
DELETE /tasks/:id(.:format) tasks#destroy
students GET /students(.:format) students#index
POST /students(.:format) students#create
new_student GET /students/new(.:format) students#new
edit_student GET /students/:id/edit(.:format) students#edit
student GET /students/:id(.:format) students#show
PUT /students/:id(.:format) students#update
DELETE /students/:id(.:format) students#destroy
courses GET /courses(.:format) courses#index
POST /courses(.:format) courses#create
new_course GET /courses/new(.:format) courses#new
edit_course GET /courses/:id/edit(.:format) courses#edit
course GET /courses/:id(.:format) courses#show
PUT /courses/:id(.:format) courses#update
DELETE /courses/:id(.:format) courses#destroy
grades_upload_grade POST /grades/upload_grade(.:format) grades#upload_grade
students_upload_student POST /students/upload_student(.:format) students#upload_student
root / home#index

How to allow other view have the delete_class_path in RoR?

I have a object called "category", in my view/store/manage.html.erb, I want to do this :
<%=link_to_remote category.name, :url => delete_category_path(category),
:confirm => 'Are you sure?', :method => :delete%>
But it show me the NoMethodError, how can I do that?
This is the error from RoR:
undefined method `delete_category_path' for #<ActionView::Base:0x103490da0>
This is my manage method in the store_controller.rb:
def manage
#categories = Category.all
#products = Product.all
#category = Category.new(params[:category])
end
You should use just category_path(#category). Both URL's are the same and only the HTTP method changes. In your case it would be:
<%=link_to_remote category.name, :url => category_path(category),
:confirm => 'Are you sure?', :method => :delete%>
As you can see with rake routes:
categories GET /categories(.:format) {:controller=>"categories", :action=>"index"}
POST /categories(.:format) {:controller=>"categories", :action=>"create"}
new_category GET /categories/new(.:format) {:controller=>"categories", :action=>"new"}
edit_category GET /categories/:id/edit(.:format) {:controller=>"categories", :action=>"edit"}
category GET /categories/:id(.:format) {:controller=>"categories", :action=>"show"}
PUT /categories/:id(.:format) {:controller=>"categories", :action=>"update"}
DELETE /categories/:id(.:format) {:controller=>"categories", :action=>"destroy"}
The actions show, update and destroy share the same category_path.
You have to add to the config/routes.rb the next following code:
map.resources :categories
(Resources - create paths for the next commands, create, update, delete, new, edit).
For more information read in the Rails Way book or in the tutorials rubyonrails.com.

Resources