Nested Routes - Ruby on Rails - ruby-on-rails

I'm trying to get a nested route like "project/:project_id/task/:task_id", but I'm not having any luck. I've set up my routes file like this:
Rails.application.routes.draw do
get 'sessions/create'
devise_for :users, path: '', path_names: { sign_up: 'users/sign_up'}
get 'teams/sign_up' => 'teams#new', as: 'new_team'
get 'teams/:id/users/:user_id' => 'teams#users_index'
get 'teams/:team_id/users/:id/complete' => 'users#show_complete', as: 'user_complete'
get 'projects/:id/tasks', to: 'projects#tasks_index'
get 'projects/:id/tasks/:id', to: 'tasks#show'
get 'teams/:id/projects/new' => 'projects#new', as: 'new_project'
post 'teams/:id/projects' => 'projects#create', as: 'projects'
root 'static#index', as: 'root'
get '/auth/twitter/callback' => 'sessions#create'
#resources :tasks do
#member do
# get :toggle_status
#end
#end
resources :projects do
resources :tasks, except: [:index], controller: 'projects/tasks'
end
resources :users, only: [:show]
resources :teams, except: [:new]
end
But I keep getting a error with my link in the projects.show.html, which is setup like this:
<h2><%= #project.name %></h2>
<%= form_for #task do |f| %>
<%= f.hidden_field :project_id, value: #project.id %>
<%= f.hidden_field :user_id, value: current_user.id %>
<%= f.label :notes %>: <%= f.text_field :notes %>
<%= f.submit "Add Task" %>
<% end %>
<% if #project.tasks.any? %>
<table class="table">
<tr>
<th>Task</th>
</tr>
<% #project.tasks.each do |task| %>
<tr>
<td>
<%= link_to task.notes %>
<%= task.status %>
</td>
<td>
<% if !task.id.nil? %>
<%= link_to "Change Status", toggle_status_task_path(task) %>
<% end %>
</td>
</tr>
<% end %>
</table>
<% end %>
<%= link_to "Edit Project", edit_project_path(#project) %> | <%= link_to "Delete Project", project_path(#project), method: :delete %>
I know I'm supposed to add a path after "<%= link_to task.notes %>", and I've ran rake:routes and tried numerous options of mine, but they all generate a URI error.
I'm not sure if it's how I've written my resources in the routes or what. Can anyone with nested routes expertise (in Ruby on Rails) please help me out? I'm in one of those online coding bootcamps and even instructors have been a little confused.

Can you try to change this get 'projects/:id/tasks/:id', to: 'tasks#show' to
get 'projects/:id/tasks/:id', to: 'tasks#show, as: 'project_task'.
And in your view <%= link_to task.notes, project_task_path(#project,task) %>
Hope it helps.

You would do this
<%= link_to task.notes, [#project, task] %>
This array will be used to generate a url based on the model names and ids of the items in the array (check out polymorphic routes for more info)
projects/:project_id/tasks/:id
btw, you'll also need it for the form
form_for [#project, #task] ...

Related

Rails Nested routes undefined method

I keep getting an
undefined method 'orders_path' for #<#<Class:0x007faefee50a88>:0x007faefee414e8>
when navigating to my new order path url /users/1/orders/new
Been stuck on this, not sure what the deal is.
Routes:
devise_for :users, :path => 'accounts'
resources :users, only: [:index, :show] do
resources :orders
end
root index:
<%= link_to "Create an Order", new_user_order_path(current_user.id) %>
form:
<%= form_for([#user, #order]) do |f| %>
<%= f.hidden_field :user_id %>
<div class="form-group">
<%= f.label :name %><br />
<%= f.text_field :name, autofocus: true, class: "form-control" %>
</div>
<% end %>
new:
<h1>New Order</h1>
<%= render 'form' %>
<%= link_to 'Back', user_orders_path(#user) %>
When you write this:
<%= form_for(#order) do |f| %>
Rails is looking for orders_path, but you don't really have such a route as you have defined your orders resource nested under the users resource. So, you have to pass both: #user and #order to the form like this:
<%= form_for([#user, #order]) do |f| %>
# your code goes here
<% end %>
If you write the form this way, then Rails will look for this path: user_orders_path which will match your defined route and will work and you won't get this error anymore:
undefined method 'orders_path' for #<#<Class:0x007faefee50a88>:0x007faefee414e8>
So, this will fix your current issue. But, there is another issue in your new.html.erb file where you currently have this:
<%= link_to 'Back', user_orders_path %>
You have to pass the #user as an argument to this method:
<%= link_to 'Back', user_orders_path(#user) %>
otherwise, it will fail again.
Hope this helps to solve your problems.
Since orders is nested on top of users, the form_for declaration will need to include both the user, and the order objects.
<%= form_for([#user, #order]) do |f| %>
Your new template will also need to have a reference to the given user.
<%= link_to 'Back', user_orders_path(#user) %>

Ruby on rails: Multiple submit_tag on the same form

How can I have multiple submit_tag buttons on the same form?
For now I got it working only for one button, but I'm not sure how to get form_tag to handle multiple paths.
Routes.rb
resources :actions do
end
root 'home#start'
match '/home/add', to: 'home#add', via: 'get'
match '/home/subtract', to: 'home#subtract', via: 'get'
match '/home/multiply', to: 'home#multiply', via: 'get'
Start.html.erb
<%= form_tag "/home/add",:method => "get" do %>
<p></p>
<p>
<%= label_tag :entered, "Please enter value:" %> </br>
<%= text_field_tag :entered %>
</p>
<p></p>
<p>
<%= label_tag :entered2, "Please enter value:" %> </br>
<%= text_field_tag :entered2 %>
</p>
<%= submit_tag "add", :controller => "home", :action => "add" %>
<%= submit_tag "subtract", :controller => "home", :action => "subtract" %>
<%= submit_tag "multiply", :controller => "home", :action => "multiply"%>
<% end %>
Please advise.
Thank you in advance.
I don't know if you can make it go to different path. But would something like this help?
Just have one action and do stuff in your controller based on the submit button that was clicked. You routes will look like
*Routes.rb*
resources :actions do
end
root 'home#start'
match '/home/operation', to: 'home#add', via: 'get'
You view will be
<%= form_tag "/home/operation",:method => "get" do %>
<p></p>
<p>
<%= label_tag :entered, "Please enter value:" %> </br>
<%= text_field_tag :entered %>
</p>
<p></p>
<p>
<%= label_tag :entered2, "Please enter value:" %> </br>
<%= text_field_tag :entered2 %>
</p>
<%= submit_tag "Add"%>
<%= submit_tag "Subtract"%>
<%= submit_tag "Multiply"%>
<% end %>
In your controller
class HomeController < ApplicationController
def operation
send(params[:commit].downcase) #params[:commit] will have one of the values "Add", "Subtract", "Multiply"
end
private
def add
#do something
end
def subtract
#do something
end
def multiple
#do something
end
end

rails search nested resource

i try to search something in my objet calendar but all the time when i click on submit i get this error.
And i dont really understand why ?
The request method POST is inappropriate for the URL /.
_search.html.erb
<%= form_for user_calendars_path([#user, #calendar]), :method => 'get' do %>
<%= text_field_tag :search, params[:search_condition], :id => 'search_field' %>
<%= submit_tag "Search" %>
<p>hello </p>
<% end %>
calendar_controller
def index
#search = #user.calendar.search(params[:search_condition])
#content_calendars = #user.calendar.all
#content_calendars_by_dates = #content_calendars.group_by(&:published_on)
#date = params[:date] ? Date.parse(params[:date]) : Date.today
end
route.rb
resources :users do
resources :calendars
end
Try this:
<%= form_tag user_calendars_path(#user, #calendar), :method => 'get' do %>
<%= text_field_tag :search, params[:search_condition], :id => 'search_field' %>
<%= submit_tag "Search" %>
<p>hello </p>
<% end %>

How to add class in rails 2.3.5 to link_to

I have got following link_to tag But I don't know how to add html class attribute to it and explain me code edit_course_path(course) .. does. I am new to rails
<% #courses.each do |course| %>
<li class="list<%=cycle('odd', 'even')%>">
<div class="category-edit"><%= link_to "#{t('edit_text')}", edit_course_path(course) if permitted_to? :edit, :courses %></div>
<div class="category-delete"> <%= link_to(t('delete_text'), course_path(course), :method => 'delete', :confirm => "#{t('delete_confirm_msg')}") if permitted_to? :destroy, :courses %></div>
</li>
<% end %>
Generally like so:
<% for employee in #employees %>
<%= link_to 'Edit', edit_employee_path(employee) if permitted_to? :update, employee , :class => 'some-class'%>
<% end %>

Path helpers in a loop

I have a Foo that :has_many Bars. GET Foo#index shows all of the Bars. View looks like this:
<% #foos.each do |foo| %>
<% foo.bars.each do |bar| %>
<%= link_to 'Download', download_bar_path %>
<%= link_to 'New', new_bar_path( :foo => foo.id ) %>
<% end %>
<% end %>
There is a def download in Bars controller and a route:
resources :bars do
member do
get 'download'
end
end
rake routes shows
download_bar GET /bars/:id/download(.:format) {:action=>"download", :controller=>"bars"}
and URL /bars/1/download really works, but the first link in the view (download_bar_path) doesn't. It says No route matches {:action=>"download", :controller=>"bars"}.
What can be the problem?
<% #foos.each do |foo| %>
<% foo.bars.each do |bar| %>
<%= link_to 'Download', [:download, bar] %>
<%= link_to 'New', [:new, :bar] %>
<% end %>
<% end %>
You didn't specified the bar to download, you need to add it by changing this line
<%= link_to 'Download', download_bar_path(bar) %>

Resources