question about using link_to in template and in console

I have a question about using link_to in template and in console

Say I do rails new blah, I make a model called User, I make a table users, each user has a field called ‘name’. I have resources :users, in config/routes.rb And I add some users.

in template, I can do

<% @z=User.find_by(name:“bob”) %>

<%= link_to ‘aaa’,@z %>

I understand that it will take that variable @z which is a reference to a user, and will convert it to user_path(@z.id)

And I can do for example

<%= link_to ‘aaa’,user_path(@z.id) %>

And in the console, I can say

puts app.user_path(1)

/users/1

But I notice that in the console I can’t do that shorthand as shown above with @z

I can say

irb(main):003:0> helper.link_to(“aaa”,app.user_path(4))

=> “<a href=”/users/4">aaa"

#<User id: 3, name: “bob”>

user=User.find_by(name:“bob”)

irb(main):005:0> helper.link_to(“aaa”,user)

Traceback (most recent call last):

1: from (irb):5

ArgumentError (arguments passed to url_for can’t be handled. Please require routes or provide your own implementation)

irb(main):006:0>

And also, I notice that in the template, while I can say user_path(@z.id), I can’t say app.user_path(@z.id)

Why is it that in the console, I can’t use that shorthand of writing @z or user, in a link_to, with that variable as an argument, when that variable points to a user. Whereas I can in a template.

And why is it that in a template, I can’t refer to app.user_path only to user_path ?

Thanks

actually it uses to_param to convert to the path (fallsback to id if not defined I think).

you could do something like app.instance_eval { link_to “bob”, @bob } and app.instance_eval { link_to “bob”, user_path(@bob) } etc.

I all comes down to the context where the code is executed. Rails console context (self) is the “main” object, while, in the view, the context is the view class which includes a lot of helpers.

The main object on the console has an “app” method, a “helpers” methods, etc, but the view class does not (it includes some methods on itself). That’s why you can’t call “app.something” on the view, there’s no “app”.

The case of the object as an argument is similar, link_to, under th hoods, uses “url_for”, if you do app.url_for(@z) on the console you’ll get the url but link_to is running on a different context (you are calling “helper.link_to”, not just “link_to”).

They are just different context with different available methods (check self.methods on both the console and when rendering a view an you’ll see it’s really diferent)

thanks local and ariel