Reputation: 127
I'm trying to make an API which passes the filled form symbols, new.html.erb, to an object in another view, using form_for and params[], show.html.erb, that shows a post with the filled form, but I can't find the right way, or the best way to do it, something goes wrong when I try to pass the params to the other view
views/recipes/new.html.erb
<%= form_for :recipe, url: recipes_show_path do |r| %>
Título: <%= r.text_field :title%><br />
Tipo da Receita: <%= r.text_field :recipe_type%><br />
Cozinha: <%= r.text_field :cuisine %><br />
Dificuldade: <%= r.text_field :dificulty %><br />
Tempo de Preparo: <%= r.text_field :cook_time_min %><br />
Ingredientes: <%= r.text_field :ingredients %><br />
Como Preparar: <%= r.text_field :cook_method %><br />
Enviar: <%= r.submit %>
<% end %>
views/recipes/show.html.erb
<h3>Detalhes</h3>
<p><%= @recipe.recipe_type %></p>
<p><%= @recipe.cuisine %></p>
<p><%= @recipe.difficulty %></p>
<p><%= @recipe.cook_time_min %></p>
<h3>Ingredientes</h3>
<p><%= @recipe.ingredients %></p>
<h3>Como Preparar</h3>
<p><%= @recipe.cook_method %></p>
<%= link_to 'Voltar', root_path %>
recipes_controller.rb
class RecipesController < ApplicationController
def index
@recipes = Recipe.all
end
def new
recipe = Recipe.new
recipe.title = [:title]
recipe.recipe_type = [:recipe_type]
recipe.cuisine = [:cuisine]
recipe.difficulty = [:difficult]
recipe.cook_time_min = [:cook_time_min]
recipe.ingredients = [:ingredients]
recipe.cook_method = [:cook_method]
recipe.save
redirect recipes/show
end
def show
@recipe = Recipe.find(params[:id])
end
end
routes.rb
Rails.application.routes.draw do
get 'recipes/show'
get 'recipes/new'
root to: 'recipes#index'
resources :recipes
end
Upvotes: 0
Views: 872
Reputation: 101811
Do not use symbols with form_for
. This feature has repeatedly been flagged for depreciation and is not recommended, instead pass an actual variable.
<%= form_for(@recipe) do |f| %>
# ...
<% end %>
Avoid explicitly adding a URL to the form - if you embrace convention over configuration you can reuse the same form for the edit/update action.
If what you want is to actually persist the object to the database you would set it up like so:
# config/routes.rb
resources :recipies, only: [:new, :create, :show]
# get rid of that other junk
class RecipesController < ApplicationController
# GET /recipies/:id
def show
@recipe = Recipe.find(params[:id])
end
# GET /recipies
def index
@recipes = Recipe.all
end
# this action just displays a form
# GET /recipies/new
def new
@recipe = Recipe.new
end
# this action handles the form submission and saves the record in the db
# POST /recipies
def create
@recipe = Recipe.new(recipe_params)
# don't just assume the input is valid!
if @recipe.save
redirect_to @recipe # redirects to recipes/:id
else
render :new # just renders the view - does not redirect
end
end
private
# this method whitelists the parameters we want to assign
# if you are copying a hash key by key you're doing it wrong
def recipe_params
params.require(:recipe).permit(
:title, :recipe_type, :cuisine, :difficult,
:cook_time_min, :ingredients, :cook_method
)
end
end
What you want to do is really strange. If you really wanted to pass an unpersisted object through a redirect you would have to place all the parameters in the query string:
# recipes/show?recipe[title]="Foo"&recipe[recipe_type]="Bar"...
redirect_to(recipe_path(recipe: recipe.attributes))
And then extract out all the parameters again on the other end:
@recipe = Recipe.new(recipe_params)
That's why you render instead of redirecting when a record is invalid. And when you redirect to the new record you just use the id of the record instead of trying to pass all the attributes.
Upvotes: 2
Reputation: 3002
Here is what you have to do
First adjust your new
method
def new
@recipe = Recipe.new
end
Now build out a create
method to handle saving the data.
def create
recipe = Recipe.new <-- I think you will need this with this set up
recipe.title = params[:recipe][:title]
recipe.recipe_type = params[:recipe][:recipe_type]
recipe.cuisine = params[:recipe][:cuisine]
recipe.difficulty = params[:recipe][:difficult]
recipe.cook_time_min = params[:recipe][:cook_time_min]
recipe.ingredients = params[:recipe][:ingredients]
recipe.cook_method = params[:recipe][:cook_method]
if recipe.save
redirect_to recipe
else
# Probably some error handling?
end
end
Change where the form submits to (the variable has to match what is set in the new
method so it submits to the create
method, saves the data and then redirects to the show method.
<%= form_for(@recipe) do |r| %>
Upvotes: 1