Confusion About Passing Instance Variables to Redirect_To Method. as Seen in Rails Guides

Confusion about passing instance variables to redirect_to method. As seen in Rails Guides

redirect_to documentation

redirect_to(options = {}, response_status = {}) Redirects the
browser to the target specified in options.
Record - The URL will be generated by calling
url_for with the options, which will reference a named URL for that
record.

So when one does redirect_to(@book) @book is a specific record with an id .

Thus, the associated records (in this case @book) show method is used as a template.

In addition to above, if you look at the routes.rb file which defines these paths you will notice

resources :books

Now this route is essentially translated as (you can see by running rake routes)

    books GET    /books(.:format)                   books#index
POST /books(.:format) books#create
new_book GET /books/new(.:format) books#new
edit_book GET /books/:id/edit(.:format) books#edit
book GET /books/:id(.:format) books#show
PUT /books/:id(.:format) books#update
DELETE /books/:id(.:format) books#destroy

Notice the book GET /books/:id books#show - which gets matched when you do redirect_to(@book)

ruby on rails redirect_to with instance variable

It redirects (through Rails magic located in url_for, if I remember correctly) to article's show page.

Pass an instance object as the parameter into redirect_to method

The routes are defined in the routes.rb file. For more details, refer http://guides.rubyonrails.org/routing.html.
To see the routes of your application there are two ways i.e.

a. Execute rake:routes in your terminal.
b. Open localhost:3000/anywrongroute

It will display all the routes in your application.


  1. Yes

How is this sent to the Show action

If you define your routes using the Rails convention of defining RESTful routes i.e. resources :articles in your routes.rb file, then redirect_to @article will take you to the show page of this particular @article instance. Rails is doing the underlying magic here.

When you write resources :articles in your routes.rb file, Rails is generating these routes for you automatically:

      Prefix Verb   URI Pattern                  Controller#Action
articles GET /articles(.:format) articles#index
POST /articles(.:format) articles#create
new_article GET /articles/new(.:format) articles#new
edit_article GET /articles/:id/edit(.:format) articles#edit
article GET /articles/:id(.:format) articles#show
PATCH /articles/:id(.:format) articles#update
PUT /articles/:id(.:format) articles#update
DELETE /articles/:id(.:format) articles#destroy

So you have this particular route which is mapped to articles controller's show action:

article GET    /articles/:id(.:format)      articles#show

This route is matched when you do: redirect_to @article and that is why it's taking you to the show page of this @article.

To know more about how RESTful routes works, see this Rails tutorial

Routing in Rails

You have defined resources :articles on your config/routes.rb file which is a rails helper method that generates the following routes when you run rake routes | grep articles on your terminal shell

            articles GET    /articles(.:format)                                                   articles#index
POST /articles(.:format) articles#create
new_article GET /articles/new(.:format) articles#new
edit_article GET /articles/:id/edit(.:format) articles#edit
article GET /articles/:id(.:format) articles#show
PATCH /articles/:id(.:format) articles#update
PUT /articles/:id(.:format) articles#update
DELETE /articles/:id(.:format) articles#destroy

The statement redirect_to @article at the end of def create ... end block is translated by rails to 'redirect_to /articles/@article.id' which is responsible for redirecting the response to articles#show action defined in app/controllers/articles_controller.rb

rails redirect_to post

I would need to see the full example for a complete answer, but my guess is that the author just picked "Post" as the name of one of the models and didn't realize it might cause confusion to the reader with the POST action.

As part of the HTTP Protocol (http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html), you actually can't redirect to a POST action. Or, more explicitly, whatever destination you are calling with a redirect needs to return with the GET method.

Hope that helps!

undefined method `items' for nil:NilClass in @cart.items.each

after you redirect to cloths_path from ItemController's create action @cart instance variable will not be available to cloth's controller index action. to need to reset it some how in index action

for eg: - 

you can pass cart id to it and find it in index cloth's action

redirect_to clothes_path, card_id: @cart.id

and in cloth's index action do

@cart = Cart.find params[:cart_id]


create a mathod in application controller, and after u create a new cart, save its id in session, like

session[:cart] = @cart.id

def current_cart
@cart = Cart.find session[:cart_id]
end

and in view use current_cart method instead of @cart

undefined local variable or method 'gallery'

Try replacing your link_to method with something like: <%= link_to 'Show', :controller => "photos", :action => :your_method, :params1 => gallery %>.

Then in your PhotoController you can use: @my_gallery = params[:params1] to access your gallery item.

Some documentation on routes:

http://guides.rubyonrails.org/routing.html

Rails Associations - Strong Parameters Build

First make a few changes in the TeamsController as below:

class TeamController < ApplicationController

before_action :authenticate_user!

def new
## Set "@team" and build "players"
@team = current_user.build_team
@team.players.build
end

def create
@team = current_user.build_team(team_params)
if @team.save
## Redirect to teams show page
redirect_to @team, notice: 'Team was successfully created.'
else
## In case of any error while saving the record, renders the new page again
render action: 'new'
end
end

private

# I can add the player param as nested i.e. .permit(:name, :players => [:name])
# but then build_team complains about receiving an array.

def team_params
## Permit players_attributes
params.require(:team).permit(:name, players_attributes: [:id, :name])
end

end

After this, update the view as below:

<%# Changed "form_for :team" to "form_for @team" %>
<%= form_for @team do |f| %>

<%= f.label :name %><br />
<%= f.text_field :name %>

<%= f.fields_for :players do |player| %> <%# Changed "|players|" to "|player|" %>
<%= player.label :name %> <%# Changed "player_name" to "name" and "players" to "player" %>
<%= player.text_field :name %> <%# Changed "players" to "player" %>
<% end %>

<div><%= f.submit "Create Team" %></div>

<% end %>

Set an instance variable @team in new action and build the players for that @team.
Use @team instance variable as an argument for form_for in your view code.

I have also suggested a few tweaks in the create action, so you know if the team is saved or not.
And fixed the team_params method to permit the nested attributes of players.

UPDATE

Using @team as an argument to form_for method is resource-oriented style and much preferred way.
Read this pretty good description about usage of form_for to get a better idea.
You can still implement the required code while using :team but its not preferred way of doing it.

Example using :team:

<%= form_for :team do |f| %> 

<%# ... %>

<%= f.fields_for :players, f.object.players.build do |player| %> <%# build the players for the team %>
<%# ... %>
<% end %>

<%# ... f.submit "Create Team" %>

<% end %>

fields_for in your case would iterate over players (@team.players) belonging to a particular team (@team). If there are no players then you won't see any fields for players in the form, which is why you build the players so you at least get some blank fields for players to input which is why when using accepts_nested_attributes_for you need to build the nested attributes. You can build them either at controller level(as shown in above suggested code) or within the form.

Example for "within the form":

<%= form_for @team do |f| %> 

<%# ... %>

<%= f.fields_for :players, @team.players.build do |player| %> <%# build the players for @team %>
<%# ... %>
<% end %>

<%# ... f.submit "Create Team" %>

<% end %>


Related Topics



Leave a reply



Submit