Link_to parameters ignored

Hi,

I’ve faced a couple of times the next problem.

I have a link to like:

<%= link_to ‘Add comment’, :action => ‘add_comment’, :program_id =>
program.program_name, :user => @username %>

I have function in the right controller:

def add_comment
@program_id = params[:program_id]
@user = User.find(session[:uid])
end

And that fails with:
Couldn’t find Program with ID=add_comment

When I check the request sent to the server:

Processing ProgramsController#show (for 127.0.0.1 at 2008-02-27
13:37:19) [GET]
Session ID: BAh7…
Parameters: {“user”=>“user1”,
“program_id”=>“The program”,
“action”=>“show”,
“id”=>“add_comment”,
“controller”=>“programs”}

←[4;36;1mProgram Columns (0.010000)←[0m ←[0;1mSHOW FIELDS FROM
programs←[0m
←[4;35;1mProgram Load (0.010000)←[0m ←[0mSELECT * FROM programs
WHERE (programs.id = 0) ←[0m


The DB request fails because it is using “id”=>“add_comment” as
argument. But I have not defined the id. That is added automatically.

Plus the action received at the server is now “show”. When I have
specified “add_comment”.

What is going on, any hints?

Thanks.

i guess you have added a RESTful route for this?

map.resource :programs

your link generates:
/programs/add_comment?program_id=… (and it’s a GET request as with
ever normal link)

and the RESTful url for the show action of this controller is:
/programs/:id
when it’s a GET request, this routes to the show action. So the
resource sees “add_comment” as :id

In a RESTful design, adding comments should be handled in the
CommentsController, not the ProgramsController anyways.

On 27 Feb., 12:43, comopasta Gr [email protected]

in Rails 2.0 scaffold generates a RESTful controller and also adds the
RESTful route to the routes.rb
Have a look at the routes file and you will see it.

You can see what i described in my above reply in your own controller
code genrated bx the scaffold:

GET /programs/1

GET /programs/1.xml

def show

a link like /programs/1 is routed to the show action.
same for /programs/add_comments, as Rails doesn’t restrict URLs to
integer id values (we all love permalinks don’t we?)
thats why your error happens.

On 27 Feb., 13:42, comopasta Gr [email protected]

Thorsten wrote:

i guess you have added a RESTful route for this?

map.resource :programs

Well no I haven’t done anything like that. It is a basic rails app
generated with scaffold. Should I post here some configuration file to
help clarifying the issue?

To the main scaffold I have added a new add_comment.html.erb
I try to open that one from the index.html.erb

This is my controller. I have some basic authentication also in place
but that should be ok and is working.

class ProgramsController < ApplicationController

before_filter :check_auth, :except => :index

def add_comment()
@program_id = params[:program_id]
@user = User.find(session[:uid])
end

def secret
puts session[:uid]
@user = User.find(session[:uid])
puts @user.username
redirect_to :action => ‘list’
end

def log_out
session[:uid] = nil
redirect_to :controller => ‘main’
end

GET /programs

GET /programs.xml

def index
@isLogged = false
if session[:uid]
@user = User.find(session[:uid])
@isLogged = true
@username = @user.username
end

@programs = Program.find(:all)
@multiplier = -25


respond_to do |format|
  format.html # index.html.erb
  format.xml  { render :xml => @programs }
end

end

GET /programs/1

GET /programs/1.xml

def show
@program = Program.find(params[:id])

respond_to do |format|
  format.html # show.html.erb
  format.xml  { render :xml => @program }
end

end

GET /programs/new

GET /programs/new.xml

def new
@program = Program.new

respond_to do |format|
  format.html # new.html.erb
  format.xml  { render :xml => @program }
end

end

GET /programs/1/edit

def edit
@program = Program.find(params[:id])
end

POST /programs

POST /programs.xml

def create
@program = Program.new(params[:program])

respond_to do |format|
  if @program.save
    flash[:notice] = 'Program was successfully created.'
    format.html { redirect_to(@program) }
    format.xml  { render :xml => @program, :status => :created, 

:location => @program }
else
format.html { render :action => “new” }
format.xml { render :xml => @program.errors, :status =>
:unprocessable_entity }
end
end
end

PUT /programs/1

PUT /programs/1.xml

def update
@program = Program.find(params[:id])

respond_to do |format|
  if @program.update_attributes(params[:program])
    flash[:notice] = 'Program was successfully updated.'
    format.html { redirect_to(@program) }
    format.xml  { head :ok }
  else
    format.html { render :action => "edit" }
    format.xml  { render :xml => @program.errors, :status => 

:unprocessable_entity }
end
end
end

DELETE /programs/1

DELETE /programs/1.xml

def destroy
@program = Program.find(params[:id])
@program.destroy

respond_to do |format|
  format.html { redirect_to(programs_url) }
  format.xml  { head :ok }
end

end

private
def check_auth
unless session[:uid]
flash[:error] = ‘You need to be logged in to access this panel’
redirect_to :controller => ‘main’
#redirect_to :action => ‘list’
end
end

end

Thanks.

comopasta Gr wrote:

Hi,

I’ve faced a couple of times the next problem.

I have a link to like:

<%= link_to ‘Add comment’, :action => ‘add_comment’, :program_id =>
program.program_name, :user => @username %>

Processing ProgramsController#show (for 127.0.0.1 at 2008-02-27
13:37:19) [GET]
Session ID: BAh7…
Parameters: {“user”=>“user1”,
“program_id”=>“The program”,
“action”=>“show”,
“id”=>“add_comment”,
“controller”=>“programs”}

Plus the action received at the server is now “show”. When I have
specified “add_comment”.

What is going on, any hints?

Thanks.

You might try adding the ‘{’ and ‘}’ around the action. Looking on the
documentation all the examples have those braces. I have had link_to and
link_to_remote do strange things when I leave those off. Good luck,

-Shandy

While I believe Thorsten is correct about the part that the scaffold
is playing in the error, you’ll need a couple more pieces to pull this
together.

First, the RESTful ProgramsController is going to assume that you’re
dealing with the Program model, so it expects :id rather
than :program_id. That will help with creating the correct route.

Second, to support ‘add_comment’ as a non-standard (ie., not a default
Rails RESTful route) path you’ll have to modify your /config/
routes.rb The scaffold should have added a line like the one Thorsten
mentioned. You’ll want to change it to something like this:

map.resources :programs, :member=>{:add_comment=>:post}

That tells the routing system that you want to find one member in the
collection of Program routes (so expect an :id entry in the params
hash), that the action/method handling it will be called add_comment,
and it should only respond when accessed via http POST.

HTH,
AndyV

Hi again!

Thanks all for your great comments.
I actually tried to play intially with the {…} and so but didn’t help.

REST was one of my pending (one of many) areas and it looks like time
has come. I just went through a perfect set of articles about the REST
for me. I think I might have a basic knowledge of the main concepts.

Here’s a link to the set of articles, started with Rails 1.2 and updated
to 2.0: http://www.softiesonrails.com/search?q=rest+101


What I’ve just done is to generate separate scaffolds for my resources.
So now I really have a commentsController to use. I try to stick to the
REST methods as much as possible.

In a quick test I just created a few programs and added a link_to so I
can access from there a bunch of comments. It was working from scratch.
Next thing will be filtering the comments I want to see based on the
program id or name but sticking to the REST rules.

I hope I’m in the right direction, if not I think I’m getting closer
anyway :sunglasses:

Thanks again for your comments!

Cheers.

Best to modify the CommentsController.

On Feb 28, 6:25 am, comopasta Gr [email protected]

Hi,

I’ll continue my reading but…

Now I have created:

  • Program 1

  • Program 2

  • Comment 1 for Program 1 name

  • Comment 2 for Program 1 name

  • Comment 1 for Program 1 name

So basically there are two comments for program 1 and one comment for
program 2


I know that in Programs index I can use <%= link_to ‘View comments’,
:controller => ‘comments’, :action => ‘index’ %>

And then I can see all the comments for all programs.

But I want to see only to comments for a given program. So I guess I can
add the program.program_name somehow in the link_to.

But do I need to add a new method to the comments controller? Or should
I modify the comments controller index/show method so that it would take
an argument and find the records accordingly? What is the proper
approach?

As said I’ll keep reading stuff also.

Thanks!