Mikhah Mikhah - 3 months ago 12
Ruby Question

Can't change root route rails

I'm creating a simple Todo list application in rails and I have the next problem:

I have a task that

belongs_to
project
I've created a template -
projects/show.html.erb

And I can't set it to be the
root page
of my app, as I can see from the debugger - root is always
projects#index
action

P.S. I need show to be the root page cause I can't use this form in index action

<%= form_for [@project, @task],remote: true do |f| %>
<%= f.input :body,class: 'form-control' %>
<%= f.submit 'Add task', class: 'btn' %>
<% end %>


projects controller

class ProjectsController < ApplicationController
before_action :load_project, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!

def index
@projects = current_user.projects unless current_user.nil?
end

def show
@task = @project.tasks.new
end

def new
@project = current_user.projects.new
end

def edit
end

def create
@project = current_user.projects.create(project_params)

if @project.save
redirect_to root_path
else
render :new
end
end

def update
if @project.update(project_params)
redirect_to @project
else
render :edit
end
end

def destroy
@project.destroy
redirect_to projects_path
end

private

def load_project
begin
@project = Project.find(params[:id]) #raises an exception if project not found
rescue ActiveRecord::RecordNotFound
redirect_to projects_path
end
end

def project_params
params.require(:project).permit(:name, :user_id)
end

end


Routes.rb

Rails.application.routes.draw do
devise_for :users, :controllers => { :omniauth_callbacks => "callbacks" }
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
root 'projects#index'


resources :projects do
resources :tasks
end




end


And routes generated by rake routes

todo$ rake routes
Prefix Verb URI Pattern Controller#Action
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_facebook_omniauth_authorize GET|POST /users/auth/facebook(.:format) callbacks#passthru
user_facebook_omniauth_callback GET|POST /users/auth/facebook/callback(.:format) callbacks#facebook
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
root GET / home#index
project_tasks GET /projects/:project_id/tasks(.:format) tasks#index
POST /projects/:project_id/tasks(.:format) tasks#create
new_project_task GET /projects/:project_id/tasks/new(.:format) tasks#new
edit_project_task GET /projects/:project_id/tasks/:id/edit(.:format) tasks#edit
project_task GET /projects/:project_id/tasks/:id(.:format) tasks#show
PATCH /projects/:project_id/tasks/:id(.:format) tasks#update
PUT /projects/:project_id/tasks/:id(.:format) tasks#update
DELETE /projects/:project_id/tasks/:id(.:format) tasks#destroy
projects GET /projects(.:format) projects#index
POST /projects(.:format) projects#create
new_project GET /projects/new(.:format) projects#new
edit_project GET /projects/:id/edit(.:format) projects#edit
project GET /projects/:id(.:format) projects#show
PATCH /projects/:id(.:format) projects#update
PUT /projects/:id(.:format) projects#update
DELETE /projects/:id(.:format) projects#destroy

Answer

Why do you want the index to be show page? Well, how can you do that? The show action requires a id to be passed to the controller so that a particular project can be displayed to the user. How can you pass in a id when the user is requesting for /?

Does that make sense?

I would suggest you to leave the root to the index page. In the index view, link each project to its show page. Its unnecessary to have a nested form in the index page.

Or if you want to list all projects and tasks in the root page, modify your index view to loop through each project's tasks.

@projects.each do |project|
  # display project's information
  project.tasks.each do |task|
    # display the task information
    # display a new task button
  end
end

But you can't display the nested form like you asked. Because the form requires @project and @task which you can't determine in the index action. Maybe you can add remote: true to the "New task" and then trigger a JS response to render the form in a modal.

If this sounds new to you, please see https://launchschool.com/blog/the-detailed-guide-on-how-ajax-works-with-ruby-on-rails

This will walk through you using AJAX in your rails application.

Hope this helps!

Comments