Bringing Form Values into a Controller - Ruby on Rails - ruby-on-rails

I am trying to create a basic form where the user can change their password but needs to enter their old password in order to do it. I am having trouble verifying the user's old password. Everytime I enter an old password it says password doesn't match when I know that it does. If a replace the actual password in the authenticate field it works. How can I bring in what was entered in the form to verify the old password that was entered?
Form:
<%= form_for(#user, :url => change_password_action_path(current_user.id), html: { "role" => "form" }) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="form-group">
<%= f.label :old_password, "Old Password:", :class => "control-label" %>
<%= f.password_field :old_password, :class => "form-control" %>
</div>
<div class="form-group">
<%= f.label :password, "New Password:", :class => "control-label" %>
<%= f.password_field :password, :class => "form-control" %>
</div>
<div class="form-group">
<%= f.label :password_confirmation, "Password Confirmation:", :class => "control-label" %>
<%= f.password_field :password_confirmation, :class => "form-control" %>
</div>
<%= f.submit "Update Password", class: "btn btn-large btn-primary" %>
Controller
def change_password
#user = User.find(current_user.id)
end
def change_password_action
user = current_user.id
if User.find(user).authenticate(params[:old_password]) == false
flash[:danger] = "Password Doesnt Match: "
else
flash[:success] = "Password Match"
# Validate the new and confirm password.
end
redirect_to action: :change_password
end
Routes
get '/change_password' => 'main#change_password'
patch '/change_password_action' => 'main#change_password_action'
Rails Server Logs
Started PATCH "/change_password_action.1" for 127.0.0.1 at 2014-01-15 09:04:38 -0600
Processing by MainController#change_password_action as
Parameters: {"utf8"=>"✓", "authenticity_token"=>"yYdUx37Q7alr3SccuMVjPwCJoMgMPOaiKTesSsILlP4=", "user"=>{"old_password"=>"[FILTERED]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Update Password"}
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = 'fc1baf63bac072bfefd5ed27664ece5427ad9e64' LIMIT 1
{"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"yYdUx37Q7alr3SccuMVjPwCJoMgMPOaiKTesSsILlP4=", "user"=>{"old_password"=>"test123", "password"=>"", "password_confirmation"=>""}, "commit"=>"Update Password", "controller"=>"main", "action"=>"change_password_action", "format"=>"1"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
Redirected to http://localhost:3000/change_password
Completed 302 Found in 115ms (ActiveRecord: 0.7ms)
Started GET "/change_password" for 127.0.0.1 at 2014-01-15 09:04:39 -0600
Processing by MainController#change_password as HTML
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = 'fc1baf63bac072bfefd5ed27664ece5427ad9e64' LIMIT 1
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
Rendered shared/_error_messages.html.erb (0.1ms)
Rendered main/change_password.html.erb within layouts/application (2.6ms)
Rendered layouts/_header.html.erb (0.5ms)
Rendered layouts/_footer.html.erb (0.0ms)
Completed 200 OK in 19ms (Views: 16.2ms | ActiveRecord: 0.4ms)

It looks like you're passing the wrong parameter into your authenticate method.
Try using params[:user][:old_password] instead of params[:old_password].
The param value you want will be under the :user key, because your form_for is using a user object.
You can also see this in your server logs where the user param in your params hash is:
"user"=>{"old_password"=>"[FILTERED]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}

Related

Rails - Not Redirecting even though it says “Redirected to http://localhost:3000” in my sever

I have a form_with that works in my server but not in my brother:
My form in my view :
<%= form_with url: sessions_path, method: "post" do |f|%>
<h3 class="text-center text-info">Se Connecter</h3>
<div class="form-group">
<%= label_tag "email", "Adresse mail:", class: "text-info" %><br>
<%= f.email_field "email", class: "form-control" %>
</div>
<div class="form-group">
<%= label_tag "password", "Mot De Passe", class: "text-info" %><br>
<%= f.password_field "password", class: "form-control" %>
</div>
<div class="form-group" style="padding: 20px;">
<%= f.submit "Se connecter", class: "btn btn-info btn-md" %>
</div>
<% end %>
My controller :
def create
user = User.find_by(email: params[:email])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
redirect_to gossips_path, :notice => "Bienvenue <%= User.find_by(id: session[:user_id]).first_name %>"
else
flash.now[:danger] = 'Email ou Mot De Passe invalide'
render 'new'
end
end
My server :
Started POST "/sessions" for ::1 at 2020-10-04 13:10:25 +0200
Processing by SessionsController#create as JS
Parameters: {...}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."email" = $1 LIMIT $2 [["email", "..."], ["LIMIT", 1]]
↳ app/controllers/sessions_controller.rb:8
#<User:0x00007f667d7f36f0>
Redirected to http://localhost:3000/gossips
Completed 302 Found in 246ms (ActiveRecord: 0.2ms)
Started GET "/gossips" for ::1 at 2020-10-04 13:10:26 +0200
Processing by GossipsController#index as JS
Rendering gossips/index.html.erb within layouts/application
Gossip Load (0.4ms) SELECT "gossips".* FROM "gossips"
↳...
Rendered gossips/index.html.erb within layouts/application (75.5ms)
Completed 200 OK in 102ms (Views: 85.6ms | ActiveRecord: 12.8ms)
But my browser stay in the same page. I don't know why.
Can you help me?
<%= form_with url: sessions_path, method: "post", local: true do |f|%>
# ...
<% end %>
form_with unlike form_for defaults to remote: true. That means that the form will by default send an AJAX request and thus the redirect does nothing in the browser. You can see that its an AJAX request by:
Processing by SessionsController#create as JS

Rails nested resources redirection after update

Good day all, I'm pulling my hair out on this one, I've seen similar posts but none of them get me in the direction I'm trying to go.
That said, I've got a pretty complex app that's relying heavily on nested resources and name-spacing, when I save a record it saves perfectly
and redirects correctly. When I update that same record the URL changes but not as I would expect. I understand the flow from edit to update and
the set_input call pulling the params[:id], what I don't understand is why the URL is changing the parents resource to reflect the record ID.
/servers/1/features/rsyslog_inputs/12/edit"
changes to the following after update
/servers/12/features/rsyslog_inputs/12/edit"
LOGS
Started GET "/servers/1/features/rsyslog_inputs/12/edit" for 127.0.0.1 at 2017-12-08 12:27:55 -0600
Processing by Features::RsyslogInputsController#edit as HTML
Parameters: {"server_id"=>"1", "id"=>"12"}
RsyslogInput Load (0.6ms) SELECT "rsyslog_inputs".* FROM "rsyslog_inputs" WHERE "rsyslog_inputs"."id" = $1 LIMIT $2 [["id", 12], ["LIMIT", 1]]
Rendering features/rsyslog_inputs/edit.html.erb within layouts/application
Rendered shared/_error_messages.html.erb (0.4ms) [cache miss]
Rendered features/rsyslog_inputs/_form.html.erb (4.3ms) [cache miss]
Rendered features/rsyslog_inputs/edit.html.erb within layouts/application (6.5ms)
Rendered layouts/_shim.html.erb (0.5ms) [cache miss]
User Load (1.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
Rendered layouts/_navbar_top.html.erb (0.9ms) [cache miss]
Rendered layouts/_navbar_side.html.erb (0.5ms) [cache miss]
Completed 200 OK in 90ms (Views: 84.7ms | ActiveRecord: 1.7ms)
Here the PATCH has modified the servers/:id to reflect the id of the rsyslog_inputs and not retained its "1" as shown above
Started PATCH "/servers/12/features/rsyslog_inputs/12" for 127.0.0.1 at 2017-12-08 12:27:58 -0600
Processing by Features::RsyslogInputsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"dFt61NcQWXoKpmScrkngT47ZxDdhzMUcCyJ5fZKrdbaOVqKfLXMVeBUj20zKKHQ8wGe4fi2QEw98cLviyO4wQw==", "rsyslog_input"=>{"inputs_interface"=>"eth04", "inputs_ip_address"=>"1.1.1.1", "inputs_input_type"=>"tcp", "inputs_port_number"=>"22", "inputs_input_name"=>"test02", "inputs_tls"=>"0"}, "commit"=>"Save Input", "appliance_id"=>"12", "id"=>"12"}
RsyslogInput Load (0.7ms) SELECT "rsyslog_inputs".* FROM "rsyslog_inputs" WHERE "rsyslog_inputs"."id" = $1 LIMIT $2 [["id", 12], ["LIMIT", 1]]
(0.6ms) BEGIN
Server Load (1.0ms) SELECT "servers".* FROM "servers" WHERE "servers"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
SQL (1.0ms) UPDATE "rsyslog_inputs" SET "inputs_interface" = $1, "updated_at" = $2 WHERE "rsyslog_inputs"."id" = $3 [["inputs_interface", "eth04"], ["updated_at", "2017-12-08 18:27:58.904817"], ["id", 12]]
(0.8ms) COMMIT
Redirected to http://localhost:3000/servers/12/features/rsyslog_inputs
Completed 302 Found in 12ms (ActiveRecord: 4.0ms)
Controller
class Features::RsyslogInputsController < ApplicationController
before_action :set_input, only: [:show, :edit, :update, :destroy]
def index
# Let's search for all inputs associated with the corresponding appliance
#inputs = RsyslogInput.where(server_id: params[:server_id])
end
def create
#input = RsyslogInput.new(input_params)
#input.build_server
#input.server_id = params[:server_id]
if #input.save
flash[:notice] = "Input was successfully saved."
redirect_to server_features_rsyslog_inputs_path
else
render('new')
end
end
def destroy
if #input.destroy
flash[:notice] = "Input was successfully destoryed."
redirect_to server_features_rsyslog_inputs_path
else
flash[:alert] = "Unable to destroy #{#input.inputs_input_name}"
end
end
def update
if #input.update(input_params)
flash[:notice] = "Input was successfully updated"
redirect_to server_features_rsyslog_inputs_path
else
render('edit')
end
end
def new
#input = RsyslogInput.new
end
def edit; end
def show ;end
private
def set_input
#input = RsyslogInput.find(params[:id])
end
def input_params
params.require(:rsyslog_input).permit(:inputs_interface,
:inputs_input_type,
:inputs_ip_address,
:inputs_port_number,
:inputs_input_name,
:inputs_tls,
:server_id)
end
end
Form
<%= form_for ([:server, :features, #input]) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<br/>
<div class="form-group clients-form-container">
<%= f.label :inputs_interface, 'Input interface:', class: 'col-3 col-form-label' %>
<div class="col-3">
<%= f.text_field :inputs_interface, class: 'form-control', placeholder: 'Enter Interface: (e.g. eth0)' %>
</div>
<br/>
<%= f.label :inputs_ip_address, 'Input IP Address:', class: 'col-3 col-form-label' %>
<div class="col-3">
<%= f.text_field :inputs_ip_address, class: 'form-control', placeholder: 'Enter IP Address:' %>
</div>
<br/>
<%= f.label :inputs_input_type, 'Input type:', class: 'col-3 col-form-label' %>
<div class="col-3">
<%= f.text_field :inputs_input_type, class: 'form-control', placeholder: 'TCP/UDP' %>
</div>
<br/>
<%= f.label :inputs_port_number, 'Input port number:', class: 'col-3 col-form-label' %>
<div class="col-3">
<%= f.text_field :inputs_port_number, class: 'form-control', placeholder: 'Enter Port:' %>
</div>
<br/>
<%= f.label :inputs_input_name, 'Input Name:', class: 'col-3 col-form-label' %>
<div class="col-3">
<%= f.text_field :inputs_input_name, class: 'form-control', placeholder: 'Enter Ruleset Name)' %>
</div>
<br/>
<div class="form-inline">
<%= f.label :inputs_tls, 'Enable TLS:', class: 'col-1 col-form-label' %>
<div class="col-3">
<%= f.check_box :inputs_tls, class: 'form-control check-box-alignment' %>
</div>
</div>
</div>
<%= f.submit 'Save Input', class: 'btn btn-primary btn-lg' %>
<%= link_to 'Cancel', :back, class: 'btn btn-secondary region-btn btn-lg' %>
<% end %>
<br/>
Routes
resources :servers do
namespace :features do
resources :rsyslog_inputs
resources :rsyslog, only: :index
end
end
server_features_rsyslog_inputs GET /servers/:server_id/features/rsyslog_inputs(.:format) features/rsyslog_inputs#index
POST /servers/:server_id/features/rsyslog_inputs(.:format) features/rsyslog_inputs#create
new_server_features_rsyslog_input GET /servers/:server_id/features/rsyslog_inputs/new(.:format) features/rsyslog_inputs#new
edit_server_features_rsyslog_input GET /servers/:server_id/features/rsyslog_inputs/:id/edit(.:format) features/rsyslog_inputs#edit
server_features_rsyslog_input GET /servers/:server_id/features/rsyslog_inputs/:id(.:format) features/rsyslog_inputs#show
PATCH /servers/:server_id/features/rsyslog_inputs/:id(.:format) features/rsyslog_inputs#update
PUT /servers/:server_id/features/rsyslog_inputs/:id(.:format) features/rsyslog_inputs#update
DELETE /servers/:server_id/features/rsyslog_inputs/:id(.:format) features/rsyslog_inputs#destroy
server_features_rsyslog_index GET /servers/:server_id/features/rsyslog_inputs(.:format) features/rsyslog_inputs#index
seeing your forms, controller and the requirement, i would advice that you use the route helpers and pass in the appropriate parameters there
like in your form explicitly set the form url to
server_features_rsyslog_input(server_id: params[:server_id], id: #input.id)
and in your controller too pass in the parameters explicitly
So this actually turned out to be a redirection issue in the update method. I wasn't specifying the server_id which wouldn't allow the redirection back to the index based on the server.

Form_for work but doesn't save into table

I want to make a simple form_forbut that doesn't work fully.
I have two table:
Users -> has_many -> Cvs
this is my form :
<%= form_for(:cvs, action: "create", html: { method: :post }) do |f| %>
Nom : <%= f.text_field :nom %><br />
<%= f.submit %>
<% end %>
In my controller:
def create
#cv = Cv.new(cv_params)
#cv.save
end
With cv_params :
def cv_params
params.require(:cv).permit(:nom)
end
In my route.rb :
post 'createcv' => 'static_pages#createcv'
My controller is static_pages and my view is createcv
The field appear when I load the view, I put something but nothing is create in the table (there is no error). How can I correct that please?
EDIT:
The logs
Started GET "/createcv" for ::1 at 2015-06-16 17:22:03 +0200
Processing by StaticPagesController#createcv as HTML
User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
Cv Load (0.0ms) SELECT "cvs".* FROM "cvs" WHERE "cvs"."user_id" = ? [["user_id", 1]]
Rendered static_pages/createcv.html.erb within layouts/application (10.0ms)
Rendered layouts/_shim.html.erb (1.0ms)
Rendered layouts/_header.html.erb (2.0ms)
Rendered layouts/_footer.html.erb (1.0ms)
Completed 200 OK in 582ms (Views: 570.6ms | ActiveRecord: 0.0ms)
Started POST "/createcv" for ::1 at 2015-06-16 17:22:12 +0200
Processing by StaticPagesController#createcv as HTML
Parameters: {"utf8"=>"V", "authenticity_token"=>"28oSelskM87GZ/geLj6yl3tOrtvKktH/poBasO4pyt7I2QNKxw9HX4J+yS3cmisuzmGOGnr+6IxZdh+uQGDRDQ==", "cvs"=>{"nom"=>"hjsvqsv"}, "commit"=>"Save Cvs"}
User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
Cv Load (0.0ms) SELECT "cvs".* FROM "cvs" WHERE "cvs"."user_id" = ? [["user_id", 1]]
Rendered static_pages/createcv.html.erb within layouts/application (11.0ms)
Rendered layouts/_shim.html.erb (0.0ms)
Rendered layouts/_header.html.erb (1.0ms)
Rendered layouts/_footer.html.erb (0.0ms)
Completed 200 OK in 643ms (Views: 629.0ms | ActiveRecord: 1.0ms)
params.require(:cv).permit(:nom)
should be
params.require(:cvs).permit(:nom)
cause all params are nested inside :cvs not :cv
also, looking at your logs and route:
Processing by StaticPagesController#createcv
you need to rename your action to createcv.
Anyway, the routing in your app seems to be wrong... Unless you want it that way.
Ideally you should do something like this:
in static_pages controller, action createcv you'll initiate new CV object:
def createcv
...
#cv = Cv.new
end
and in createcv.html.erb the form would be like this:
<%= form_for #cv do |f| %>
Nom : <%= f.text_field :nom %><br />
<%= f.submit %>
<% end %>
rails will know that #cv in the form is a new object, and it will add the proper route to the form, that will point (depending on your app) to /cvs with post method.
That means when you submit the cv, action create from cv_controller should handle the rest of the process.
In this case you won't need the route you added, it should be there after you added
resources :cvs
This is just an example that might not fit your needs, cause I wouldn't know how did you named your models, controllers, etc..
The answer of Rajarshi Das is fine, only it seems to me that you want to open your form by visiting /createcv. so change your routes to:
# routes.rb
get '/createcv', to: 'static_pages#new'
post 'create', to: 'static_pages#create'
# static_pages controller
def new
#cv = Cv.new
end
def create
#cv = Cv.new(cv_params)
if #cv.save
flash[:alert] = 'Cv created!'
else
render 'new'
flash[:alert] = 'Error in form'
end
private
def cv_params
params.require(:cv).permit(:nom) # :cv must be singular
end
# static_pages/new.html.erb view
<%= form_for #cv do |f| %>
<p>
<%= f.label :nom %>
<%= f.text_field :nom %>
</p>
<%= f.submit %>
<% end %>

Devise User can't be edited

I have a Rails app using Devise for user authentication. I'm pretty sure the Devise edit user feature worked previously, but for some reason, edit/update doesn't work anymore. When I click "Update", the page just refreshes on the form. It also displays "Please review the problems below:" even though I've entered everything correctly.
The cancel account function works perfectly, however. Could the issue be the url path? If so, why does canceling the account work, while updating doesn't? I do have the user model nested within another model, but I've tried variations on the url path, none of which have worked.
Below is the form page generated by Devise and using simple_form:
.col-md-5.col-md-offset-2
%h2
Edit #{resource_name.to_s.humanize}
= simple_form_for(resource, as: resource_name, url: registration_path(resource_name) , html: { method: :put }) do |f|
= f.error_notification
.form-inputs
= f.input :email, required: true, autofocus: true
- if devise_mapping.confirmable? && resource.pending_reconfirmation?
%p
Currently waiting confirmation for: #{resource.unconfirmed_email}
= f.input :password, autocomplete: "off", hint: "leave it blank if you don't want to change it", required: false
= f.input :password_confirmation, required: false
= f.input :current_password, hint: "we need your current password to confirm your changes", required: true
.form-actions
= f.button :submit, "Update"
%h3 Cancel my account
%p
Unhappy? #{link_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete}
= link_to "Back", root_path
Update:
Here's the printout from development.log:
Started PUT "/users" for 127.0.0.1 at 2014-12-14 00:05:07 -0500
Processing by Users::RegistrationsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"Zhtv8rbmwIDuZO7Tv/0db7tSIGfGUEW56fqPKzkgQSo=", "user"=>{"email"=>"test3#test3.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "current_password"=>"[FILTERED]"}, "commit"=>"Update"}
[1m[36mUser Load (0.3ms)[0m [1mSELECT `users`.* FROM `users` WHERE `users`.`id` = 16 ORDER BY `users`.`id` ASC LIMIT 1[0m
[1m[35mUser Load (0.2ms)[0m SELECT `users`.* FROM `users` WHERE `users`.`id` = 16 LIMIT 1
[1m[36m (0.2ms)[0m [1mBEGIN[0m
[1m[35m (0.1ms)[0m ROLLBACK
Rendered devise/registrations/edit.html.haml within layouts/application (4.3ms)
Rendered common/_login.html.haml (0.5ms)
Completed 200 OK in 328ms (Views: 175.1ms | ActiveRecord: 0.7ms)
Here's my routes.rb file. I do have Users listed twice.
devise_for :users
root 'welcome#index'
resources :wedding_checklists do
resources :users
resources :checklist_items
end
It seems to me an error has occurred but was not shown. Please add <%= devise_error_messages! %> to your form and let me know what errors are printed out.

Create Action Doesn't Insert - Rails 3

I'm creating a profile that is associated with a member id based on Devise authentication.
When creating the profile, the values aren't inserted into the database.
Routes file.
resources :troopers do
resource :trooper_profile
end
Trooper model
has_one :trooper_profile
Trooper Profile model
belongs_to :trooper
Trooper Controller #create action
def create
#trooper = current_trooper
#profile = #trooper.build_trooper_profile(params[:profile])
respond_to do |format|
if #profile.save
format.html { redirect_to(trooper_trooper_profile_path, :notice => 'Profile was successfully created.') }
else
format.html { render :action => "new" }
end
end
end
Profile Form
<%= form_for #profile, :url => trooper_trooper_profile_path(#trooper) do |f| %>
<%= f.label :first_name %><br />
<%= f.text_field :first_name %><br /><br />
<%= f.label :last_name %><br />
<%= f.text_field :last_name %><br /><br />
<p><%= submit_tag "Create Profile" %></p>
<% end %>
Server output
Started POST "/troopers/1/trooper_profile" for 127.0.0.1 at 2011-05-20 13:04:01 +1000
Processing by TrooperProfilesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"LhT6b4xu5bIJ5kwhS74L7dpaGbuR5BTdirh9AziD+Ew=", "trooper_profile"=>{"first_name"=>"Robert", "last_name"=>"", "commit"=>"Create Profile", "trooper_id"=>"1"}
Trooper Load (0.5ms) SELECT "troopers".* FROM "troopers" WHERE ("troopers"."id" = 1) LIMIT 1
TrooperProfile Load (0.3ms) SELECT "trooper_profiles".* FROM "trooper_profiles" WHERE ("trooper_profiles".trooper_id = 1) LIMIT 1
Rendered trooper_profiles/_form.html.erb (11.7ms)
Rendered shared/_head.html.erb (1.6ms)
Rendered shared/_menutop.html.erb (1.2ms)
Rendered trooper_profiles/new.html.erb within layouts/application (18.5ms)
Completed 200 OK in 109ms (Views: 22.5ms | ActiveRecord: 0.8ms)
I've got this same setup in another application and can't see why this isn't working.
Change the following...
#profile = #trooper.build_trooper_profile(params[:trooper_profile])
It appears the parameters being passed are :trooper_profile
trooper_profile"=>{"first_name"=>"Robert", "last_name"=>"", "commit"=>"Create Profile", "trooper_id"=>"1"}
However, you're referencing :profile
If it's rendering the new view, then the profile isn't saving - perhaps it's a validation error? Does TrooperProfile require a last name (blank in your example)?

Resources