简体   繁体   中英

How To Use Link_to and why

I'm new to ruby on rails and none of the answers I've seen addressed my issue, and no question is specific enough for me

I'm attempting to use the <%= link_to %> helper on rails but it always says

undefined local variable or method trainer_index

For class i am creating a pokemon game,

my controllers, models and views look something like this:

├── app
│   ├── controllers
│   │   ├── login_controller.rb
│   │   └── trainer_controller.rb
│   ├── models
│   │   ├── login.rb
│   │   └── trainer.rb
│   └── views
│       ├── logins
│       │   ├── create.html.erb
│       │   ├── index.html.erb
│       │   ├── show.html.erb
│       │   ├── update.html.erb
│       └── trainers
│           ├── index.html.erb
│           ├── show.html.erb
│           ├── create.html.erb
│           ├── destroy.html.erb

#config/routes.rb

resources :login do
  resources :trainer
end

how would I format my link_to helper to link a button in my:

views/login/show

to my:

views/trainers/index

and why?

meaning in link_to "name", something_path

am I referencing my controller, my view, or my model?

I'd suggest you always run the command in terminal rails routes (or rake routes ) and take a look to Rails routing , understanding also CRUD verbs and actions .

rails routes takes also an argument -c (controller) so you can show the routes to the controller.


While you read the guide, run the command for your app, starting from the top level: rails routes -c login , it'll output:

 # Prefix Verb URI Pattern Controller#Action # login_index GET /login(.:format) login#index # POST /login(.:format) login#create # new_login GET /login/new(.:format) login#new # edit_login GET /login/:id/edit(.:format) login#edit # login GET /login/:id(.:format) login#show # PATCH /login/:id(.:format) login#update # PUT /login/:id(.:format) login#update # DELETE /login/:id(.:format) login#destroy 
  • The first column you have the prefix to be used as path or url helper in link_to .
  • The second columns shows the corresponding CRUD verb.
  • The URI column shows how the URI string is formatted: you cn see there is an :id which is supposed to be the id of the resource (in this case the id of login object or the object itself, often passed as variable @login ).
  • The last column shows the related controller and the method in the controller.

For example # login GET /login/:id(.:format) login#show means:

  • There is a controller file logins_controller.rb
  • The controller defines a method show: def show; end def show; end
  • There is a view folder `app\\views\\logins\\show.html.erb
  • You can reach the page at login\\123 which shows the Login object whit id = 123
  • In controller the :id parameter is available as params[:id] and its the value is 123


For the nested case of trainer , run rails routes -c trainer :

 # Prefix Verb URI Pattern Controller#Action # login_trainer_index GET /login/:login_id/trainer(.:format) trainer#index # POST /login/:login_id/trainer(.:format) trainer#create # new_login_trainer GET /login/:login_id/trainer/new(.:format) trainer#new # edit_login_trainer GET /login/:login_id/trainer/:id/edit(.:format) trainer#edit # login_trainer GET /login/:login_id/trainer/:id(.:format) trainer#show # PATCH /login/:login_id/trainer/:id(.:format) trainer#update # PUT /login/:login_id/trainer/:id(.:format) trainer#update # DELETE /login/:login_id/trainer/:id(.:format) trainer#destroy 

The story is the same, but now you have one parameter more:

  • :id ( params[:id] ) which is referred to the controller object, in this case trainer , so it can refer to the model Trainer .
  • :login_id ( params[:login_id] ) which is referred to login object, so you could use to find the record in the related model: @login = Login.find(params[:login_id]) .

From the table you can see that if you want to show all trainers:

 # login_trainer_index GET /login/:login_id/trainer(.:format) trainer#index 

Your path helper is

 login_trainer_index_path(@login.login_id) 

or just login_trainer_index_path(@login) where @login is assigned in index method of trainers_controller.rb as @login = Login.find(params[:login_id]

If you want to show a specific trainer you should look into GET:

 # login_trainer GET /login/:login_id/trainer/:id(.:format) trainer#show 

so the helper path is similar to (note the two params):

 login_trainer_path(@login, @trainer) 

You can pass also the id of Login and Trainer as arguments for the helper, depending on what's better for you do to in show method of trainers_controller.rb

Hi and welcome to Stack overflow! In Rails you use the link_to helper instead of the </a> tag from html. But the link_to also just generates an html a-tag with the right attributes. Use it like so:

<%= link_to "Text on the link", path %>

Now in order to find the right path (the href attribute of the link). You need to find the right prefix for your routes. There is a terminal command you can use to find it out: rails routes run it in your terminal and see a nice table of your routes, which controller actions they're routed to and their prefixes.

Since you have nested routes your prefix should be something like: login_trainers for the trainer#index action. Now why do we use the link to helper. It becomes clear, when you have a closer look at the route for trainer index: login/:login_id/trainers . Meaning, that there is a dynamic part in the url, representing the id of the respective record. The link_to then needs an id (or the whole instance) in order to build the right a-tag. So you can build the link_to:

<%= link_to "All trainers", login_trainers_path(@login) %>

@login coming from the controller.

One last tip: why do you nest your routes under login? Do you take care of the login into your app yourself? You should have a look at the devise gem, it is an authentication gem and is super cool!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM