Summit button not working in rails form_with edit action - ruby-on-rails

I have created a form to edit a nested resource within a rails application. The form renders properly and the submit button works with the form for the create action but causes noting to happen in when applied to the edit action. No error is triggered and the page doesn't change so it is hard to figure out where the problem exists. Similar problems seam to be the result of a syntax error but I cant seem to find one in this case however, I may be missing something. Below is the form in question.
<h1>Edit an Ingredient<h1>
<%= form_with model: [ #recipe, #ingredient ], local: true do |form| %>
<p>
<%= form.label :quantity %><br>
<%= form.text_field :quantity %>
</p>
<p>
<%= form.label :measurement %><br>
<%= form.text_area :measurement %>
</p>
<p>
<%= form.label :ingredientname %><br>
<%= form.text_area :ingredientname %>
</p>
<p>
<%= form.label :label %><br>
<%= form.text_area :label %>
</p>
<p>
<%= form.submit %>
</p>
<% end %>
<%= link_to 'Back', recipes_path %>
And the functioning "New" form...
<h1>Add an Ingredient<h1>
<%= form_with model: [ #recipe, #recipe.ingredients.build ], local: true do |form| %>
<p>
<%= form.label :quantity %><br>
<%= form.text_field :quantity %>
</p>
<p>
<%= form.label :measurement %><br>
<%= form.text_area :measurement %>
</p>
<p>
<%= form.label :ingredientname %><br>
<%= form.text_area :ingredientname %>
</p>
<p>
<%= form.label :label %><br>
<%= form.text_area :label %>
</p>
<p>
<%= form.submit %>
</p>
<% end %>
<%= link_to 'Back', recipes_path %>
And finally the relevant controller...
class IngredientsController < ApplicationController
def new
#recipe = Recipe.find(params[:recipe_id])
end
def edit
#recipe = Recipe.find(params[:recipe_id])
#ingredient = #recipe.ingredients.find(params[:id])
end
def create
#recipe = Recipe.find(params[:recipe_id])
#ingredient = #recipe.ingredients.create(ingredient_params)
redirect_to recipe_path(#recipe)
end
def update
#recipe = Recipe.find(params[:recipe_id])
#ingredient = #recipe.ingredients.find(params[:id])
end
def destroy
#recipe = Recipe.find(params[:recipe_id])
#ingredient = #recipe.ingredients.find(params[:id])
#ingredient.destroy
redirect_to recipe_path(#recipe)
end
private
def ingredient_params
params.require(:ingredient).permit(:quantity, :measurement, :ingredientname, :label)
end
end
Additionally the form is populated correctly when it is rendered leading to me believe it is not a problem with the form_with statement. Any help is appreciated!

I was able to work out the solution. The submit button was not working due to an incomplete definition of the update action in the controller. Instead of ...
def update
#recipe = Recipe.find(params[:recipe_id])
#ingredient = #recipe.ingredients.find(params[:id])
end
the update action should be defined as...
def update
#recipe = Recipe.find(params[:recipe_id])
#ingredient = #recipe.ingredients.find(params[:id])
if #ingredient.update(ingredient_params)
redirect_to #recipe
else
render 'edit'
end
end

change <%= form_with model: [ #recipe, #recipe.ingredients.build ], local: true do |form| %>
to <%= form_for [ #recipe, #recipe.ingredients.build ] do |form| %>

Related

How do I create a two-step form in rails?

I have a question for rails. I'm creating a form for user to register. What I want to do is that after the user press "Submit" button I want to redirect the user to another page which shows all the information from the form filled by the user just now (read-only).
This is my controller
class PermitsController < ApplicationController
before_action :set_permit, only: [:show, :destroy]
def index
#permits = Permit.all
end
def new
#permits = Permit.new
end
def create
#permits = current_user.permits.build(permit_params)
if #permits.save
redirect_to invoice_path
else
render 'new'
end
end
def destroy
Permit.destroy_all(user_id: current_user)
respond_to do |format|
format.html { redirect_to root_path, notice: 'Permit was successfully canceled.' }
format.json { head :no_content }
end
end
def invoice
#permits = current_user.permits(permit_params)
end
def show
#user = User.find(params[:id])
#permits = #user.permits.paginate(permit_params)
end
def update
#permits = Permit.where(user_id: current_user).take
respond_to do |format|
if #permits.update(permit_params)
format.html { redirect_to root_path}
flash[:success] = "Permit successfully updated"
format.json { render :show, status: :ok, location: #user }
else
format.html { render :edit }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_permit
#permits = Permit.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def permit_params
params.require(:permit).permit(:vehicle_type, :name, :studentid, :department, :carplate, :duration, :permitstart, :permitend)
end
end
This is the form filled by user
<% provide(:title, 'New Permit') %>
<h1>Permit Application</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#permits) do |f| %>
<%= f.label :"Vehicle" %>
<%= f.text_field :vehicle_type, class: 'form-control' %>
<%= f.label :"License Plate" %>
<%= f.text_field :carplate, class: 'form-control' %>
<%= f.label :"Student ID" %>
<%= f.text_field :studentid, class: 'form-control' %>
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
<%= f.label :"Department of applicant" %>
<%= f.text_field :department, class: 'form-control' %>
<%= f.label :permit_start %>
<%= f.date_select :permitstart, class: 'form-control' %>
<%= f.label :permit_end %>
<%= f.date_select :permitend, class: 'form-control' %>
<%= f.submit "Submit", class: "btn btn-primary" %>
<% end %>
</div>
</div>
You could add an additional action between new and create.
# config/routes.rb
resources :permit do
collection do
post :confirm
end
end
The reason that we use POST even if the route does not create a resource is that we don't want to pass any user info in the request URL.
class PermitsController < ApplicationController
# POST /permits/confirm
def confirm
#fields = %i[vehicle_type, carplate, studentid, name, department, permitstart, permitend]
#permit = current_user.permits.build(permit_params)
render :new and return unless #permit.valid?
end
end
render :new and return unless #permit.valid? shortcuts the process and renders the :new form again if the input is not valid in the first place.
Since we are using POST we need a form for both the new.html.erb and confirm.html.erb all duplicating all those inputs would not be great so lets extract them to a partial:
<% # /views/permits/_inputs.html.erb %>
<%
input_options ||= {}
input_options[:class] ||= 'form-control'
%>
<%= f.label :"Vehicle" %>
<%= f.text_field :vehicle_type, input_options%>
<%= f.label :"License Plate" %>
<%= f.text_field :carplate, input_options %>
<%= f.label :"Student ID" %>
<%= f.text_field :studentid, input_options %>
<%= f.label :name %>
<%= f.text_field :name, input_options %>
<%= f.label :"Department of applicant" %>
<%= f.text_field :department, input_options %>
<%= f.label :permit_start %>
<%= f.date_select :permitstart, input_options %>
<%= f.label :permit_end %>
<%= f.date_select :permitend, input_options %>
So lets point the new.html.erb form so that it submits to /permits/confirm:
<% provide(:title, 'New Permit') %>
<h1>Permit Application</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#permits, url: '/permits/confirm_permits_path') do |f| %>
<% render partial: :inputs %>
<%= f.submit "Submit", class: "btn btn-primary" %>
<% end %>
</div>
</div>
And create a /views/permits/confirm.html.erb view:
<% provide(:title, 'Confirm Permit application') %>
<h1>Confirm Permit application</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#permits) do |f| %>
<% render partial: :inputs, input_options: { readonly: 'readonly' } %>
<% end %>
</div>
</div>

rails 4 - param is missing or the value is empty: projecttype

A newby to rails (I am building an app to learn rails) and run in to an issue I can't find a solution to (while following the getting started guide). I have studied the guides and similar questions
This is my code:
class ProjecttypesController < ApplicationController
def index
#projecttypes = Projecttype.all
end
def show
#projecttype = Projecttype.find(params[:id])
end
def new
end
def create
#projecttype = Projecttype.new(projecttype_params)
#projecttype.save
redirect_to #projecttype
end
private
def projecttype_params
params.require(:projecttype).permit(:name, :image, :url)
end
end
The form:
<%= form_for :projecttypes, url: projecttypes_path do |f| %>
<p>
<%= f.label 'Project type' %>
<%= f.text_field :projecttype %>
</p>
<p>
<%= f.label :name %>
<%= f.text_field :name %>
</p>
<p>
<%= f.label :image %>
<%= f.file_field :image %>
</p>
<p>
<%= f.label :url %>
<%= f.url_field :url %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
What am I doing wrong?
Perhaps important... when I use this...
def create
render plain: params[:projecttype].inspect
end
It returns 'nil'.
Thanks for your help
Your code should be like this
def new
#projecttype = Projecttype.new
end
def create
#projecttype = Projecttype.create(projecttype_params)
redirect_to #projecttype
end
and use this for form
<%= form_for #projecttype do |f| %>
In your
controller file
def new
#projecttype = Projecttype.new
end
and then in your form
<%= form_for #projecttype do |f| %>

Ruby On Rails Update failed still

I have try many things but still failed, i want to implement a edit and update action here.
Below is my code
home controller:
class HomeController < ApplicationController
def index
#inputs = Person.all
end
def new
#input = Person.new
end
def create
#input = Person.new(input_params)
respond_to do |x|
if #input.save
x.html {redirect_to :action => 'index'}
else
x.html {render :action => 'new'}
end
end
end
def show
#input = Person.find(params[:id])
end
def edit
#input = Person.find(params[:id])
end
def update
#input = Person.find(params[:id])
respond_to do |x|
if #input.update(input_params)
x.html {redirect_to :action => 'index'}
else
x.html {render :edit}
end
end
end
private
def input_params
params.require(:inputs).permit(:name, :weight, :height, :color, :age)
end
end
edit.html.erb
<h1>Editing Data</h1>
<%= render 'form' %>
<%= link_to 'Show', home_path %> |
<%= link_to 'Back', home_index_path %>
form.html.erb:
<%= form_for :#input do |person| %>
<div class="field">
<%= person.label :name %><br>
<%= person.text_field :name %>
</div>
<div class="field">
<%= person.label :weight %><br>
<%= person.number_field :weight %>
</div>
<div class="field">
<%= person.label :height %><br>
<%= person.number_field :height %>
</div>
<div class="field">
<%= person.label :color %><br>
<%= person.text_field :color %>
</div>
<div class="field">
<%= person.label :age %><br>
<%= person.number_field :age %>
</div>
<div class="actions">
<%= person.submit %>
</div>
<% end %>
Routes are correct, i can lead me to the edit page, however, it shows,
first problem, edit with no data pops up
New updated
You should use form_for instead of form_tag,
<%= form_for #input do |x| %>
...
and then (depending on what #input actually is!)
<%= x.text_field :age %>
It looks like you are not binding your form to your method.
http://guides.rubyonrails.org/form_helpers.html#binding-a-form-to-an-object
gives an overview, but I'd suggest something like this for your edit:
<%= form_for #input do |f| %>
<%= render 'form', f: f %>
<%= f.submit "Update" %>
<% end %>
and in your partial - which should be _form.html.erb
<div class="field">
<p><label for = "input_name">Name</label>:
<%= f.text_field :name %>
</div>
etc.. Now assuming you have set your routes correctly, it will go back to your update method. If you have not set up your routes in the way rails expects, then you should use:
<%= form_for #article, url: **your_update_path** do |f| %>
Just add the routes path that points to your update method, when you run rake routes.

Nested Form Rails UPDATING

I hope they are good, need to do nested forms with the profile of a user and their respective car.
each user has their own profile:
class PerfilController < ApplicationController
before_filter :authenticate_user!
def index
end
def show
#usuario = current_user
#usuario.perfil ||= Perfil.new
#perfil = #usuario.perfil
end
def update
#usuario = current_user
#perfil = #usuario.perfil
respond_to do |format|
if #usuario.perfil.update_attributes(perfil_params)
format.html {redirect_to #usuario, notice: "Datos Actualizados" }
else
format.html {render action: "show"}
end
end
end
private
def perfil_params
params.require(:perfil).permit(:nombre, :apellido, :rut)
end
end
I want the fund to ensure that each time a user posts a car, you can update your profile. Deputy nested form
<%= simple_form_for(#auto) do |f| %>
<%= f.error_notification %>
<%=f.fields_for #perfil do |perfil_builder|%>
<p>
<%= perfil_builder.label :nombre %><br/>
<%= perfil_builder.text_field :nombre %>
<%= perfil_builder.label :apellido %><br/>
<%= perfil_builder.text_field :apellido %>
<%= perfil_builder.label :rut %><br/>
<%= perfil_builder.text_field :rut %>
</p>
<%end%>
<div class="form-inputs">
<%= f.association :region %>
<%= f.association :ciudad %>
<%= f.association :marca %>
<%= f.input :modelo %>
<%= f.input :version %>
<%= f.input :año %>
<%= f.input :patente %>
<%= f.association :tipo_transmision %>
<%= f.association :combustible %>
<%= f.association :tipo_vehiculo %>
<%= f.association :carroceria %>
</div>
<div class="form-actions">
<%= f.button :submit, :id => 'submit' %>
</div>
<% end %>
The problem is when you want to update does not change the user data but if you publish the article. the error in the console is: Unpermitted parameter: perfil
Best regards friends.
You are sending the request to the auto controller, hence the Unpermitted parameter: perfil error and failure to update.
You can add this to your Perfil controller:
has_many: :autos
accept_nested_attributes_for: :autos
Then in the view switch it around like this:
<%= simple_form_for(#perfil) do |f| %>
<%= f.error_notification %>
<%= f.label :nombre %><br/>
<%= f.text_field :nombre %>
...
<%=f.fields_for :auto do |auto_builder|%>
<p>
<%= auto_builder.association :region %><br/>
...
See this page for more info: http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

Couldn't find Article without an ID [duplicate]

I am trying to submit some data to db and its ok but when i am trying to retrieve those data show that Couldn't find Article without an ID.ils 4.0.1.
I am using ruby 2.0.0 and ra
def show
#article=Article.find(params[:id])
end
the ** contain error.
class ArticlesController < ApplicationController
def new
end
def create
#article = Article.new(article_params)
redirect_to #article
#article.save
end
def show
#article=Article.find(params[:id])
end
private
def article_params
params.require(:article).permit(:title, :full_name, :email, :phone_number, :message)
end
end
articles/show.html.erb
<p>
<strong>Title:</strong>
<%= #article.title %>
</p>
<p>
<strong>Full Name:</strong>
<%= #article.full_name %>
</p>
<p>
<strong>Email:</strong>
<%= #article.email %>
</p>
<p>
<strong>Phone Number:</strong>
<%= #article.phone_number %>
</p>
<p>
<strong>Message:</strong>
<%= #article.message %>
</p>
articles/new.html.erb
<h1>New Articles</h1>
<%= form_for :article, url: articles_path do |f| %>
<p>
<%= f.label :title %>
<%= f.text_field :title %>
<p>
<%= f.label :full_name %>
<%= f.text_field :full_name %>
</p>
<%= f.label :email %>
<%= f.text_field :email %>
<p>
<%= f.label :phone_number %>
<%= f.text_field :phone_number %>
</p>
<%= f.label :message %>
<%= f.text_field :message %>
<p>
<%= f.submit :send_message %>
</p>
<% end %>
You are redirecting before actually saving your article.
This:
def create
#article = Article.new(article_params)
redirect_to #article
#article.save
end
should be:
def create
#article = Article.new(article_params)
#article.save
redirect_to #article
end
And if you want to add some error handling as well:
def create
#article = Article.new(article_params)
if #article.save
redirect_to #article
else
render :new
end

Resources