0

I'm using a custom action to get the id of a project into the session, so that only relevant info for that project is shown in other areas. I've made a custom action in the projects controller, and am having trouble getting a link to work in the view to call that action. I just get an error saying "Couldn't find project without ID". I'm new to rails - I know it's probably an easy question, but help would be much appreciated, thanks!

View Code:

<%= link_to 'Select Project', :action => :select_project %>

Controller Code:

def select_project
  @project = Project.find(params[:id])
  session[:project_id] = @project.id
end

Routes:

resources :projects do
  collection do
    get :select_project
  end
end

Alternative routes code:

resources :projects do
  put 'select_project', on: :member
end
Charles
  • 50,943
  • 13
  • 104
  • 142
ecs
  • 708
  • 1
  • 14
  • 33

2 Answers2

1

I think the route generated would be select_project_projects_path.

Link:

<%= link_to 'Select Project', select_project_projects_path %>

For future reference, run rake routes to see the automatic route helpers generated by Rails.

varatis
  • 14,494
  • 23
  • 71
  • 114
  • Woops -- reversed it. I think the edit I just made should work. – varatis Jun 30 '12 at 17:06
  • That gives me the error: undefined local variable or method `project_select_project_path', will try the rake routes, thanks – ecs Jun 30 '12 at 17:09
  • @EmilyTwist It's `projects_select_project_path`. You missed an 's'. And mark this as the answer if it solves your problem. – varatis Jun 30 '12 at 17:10
  • Sorry, I pasted the wrong one. Tried both just in case - didn't work. Will try rake routes in a bit, and mark as answered then, thanks! – ecs Jun 30 '12 at 17:19
  • @EmilyTwist Ah sorry. My original answer was actually the right one -- `select_project_projects_path`. Will my edit answer to correspond to the correct solution. – varatis Jun 30 '12 at 17:22
  • Ok - still getting the 'Couldn't find Project without an ID' error though - will rake routes, thanks for help! – ecs Jun 30 '12 at 19:49
  • I've done the rake routes and you're right about the path you're suggesting. I don't understand why, but it appears as if the id of the project isn't getting passed - I don't know why as I'm accessing it from url.com/projects/1 - any ideas? Thanks! – ecs Jun 30 '12 at 19:56
  • you want to use member, not collection in your route, if you are interested in `params[:id]` containing the project id value and link_to needs to pass that value along `<%= link_to 'Select Project', select_project_projects_path(project) %>` – house9 Jun 30 '12 at 20:32
  • Hi, I've added the routes code that I've tried, it's now saying: undefined local variable or method `select_project_projects_path' - or if I add (project) after the projects_path, it's saying that is undefined. Any ideas why? Thanks for help! – ecs Jun 30 '12 at 22:46
  • Are you looping on projects and building multiple links? Or is this show, then pass @project to the path helper method – house9 Jul 01 '12 at 02:15
1

This is untested but I believe it is what you are looking for:

Routes:

resources :projects do
  member do
    post :set_current
  end
end

this should create the following:

  • Endpoint: /projects/:id/set_current POST
  • Helper: set_current_project_path

Controller

def set_current
  project = Project.find(params[:id])
  session[:project_id] = project.id
  redirect_to projects_path, :notice => "Current project set to #{project.name}"
end

Views

# index / erb tags excluded for simplicity 
@projects.each do |project|
  link_to 'Select Project', set_current_project_path(project), :method => :post
end

# show
<%= link_to 'Select Project', set_current_project_path(@project), :method => :post %>

See:

Note also the use of 'post' instead of 'get', since we are changing the state of an object (session) it is preferred to use a post not a get, otherwise users might pull up an old get request in the address bar of their browser and set their session to a project unknowingly.

like varatis said - use rake routes or CONTROLLER=projects rake routes to help with determining what your route/path helpers look like and what http verbs they are expecting


And is there a reason why it's project not @project in the controller

The @project creates an instance variable; in a rails controller instance variables are made available to the views. This set_current action will never render a view, so no reason to make an instance variable out of it.


How come you have to set it to member and not collection in the routes

any action where you want to reference params[:id] should be a member route, an alternative would be to leave it as a collection route and pass params[:project_id] and pass that in all of your link_to calls, but in this case member makes more sense.

I believe resources :projects is a short cut for this break down

member do
  get :show
  get :edit
  put :update      
  delete :destroy
end
collection do
  get :index
  get :new
  post :create
end

hopefully that clarifies your questions some?

house9
  • 20,359
  • 8
  • 55
  • 61
  • That's got it, thanks so much. How come you have to set it to member and not collection in the routes? And is there a reason why it's project not @project in the controller? Thanks! – ecs Jul 01 '12 at 18:54