Rerouting to path upon submit rails - ruby-on-rails

I'm giving the user the ability to reset their password and then reroute upon completion. However when using form tags and redirect_to, I'm getting some undesired rerouting.
Upon successful submission, the form should reroute to:
https://myherokuapp.herokuapp.com/customer_password_resets/new
but instead it reroute to:
https://myherokuapp/customer_password_resets/create.ShoyTPeAC5UAEjjWwZh_HA //the extra piece is the token id
CustomerPasswordResetsController Controller
def edit
#customer = Customer.find_by_password_reset_token!(params[:id])
end
def update
#customer = Customer.find_by_password_reset_token!(params[:id])
if #customer.password_reset_sent_at < 2.hours.ago
redirect_to new_customer_password_reset_path, :alert => "Password reset has expired."
elsif #customer.update_attributes(params[:customer])
redirect_to new_customer_password_reset_path, :notice => "Password has been reset!"
else
render :edit
end
end
customer_password_resets/edit.html.erb
<%= form_for #customer, :url => customer_password_resets_path(params[:id]) do |f| %>
<% if #customer.errors.any? %>
<div class="error_messages">
<h2>Form is invalid</h2>
<ul>
<% for message in #customer.errors.full_messages %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :password %>
<%= f.password_field :password %>
</div>
<div class="field">
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %>
</div>
<div class="actions"><%= f.submit "Update Password" %></div>

The url option is the problem there. Rails will submit alright. The new view will submit to a create action and the edit to the update

Update, the previous answer did sucesfully reroute but did not update. I need the params in order to find the user in the update model. Rake routes showed that I indeed needed to change this from post to patch !
<%= form_for #customer, :url => customer_password_resets_path, :method => :patch do |f| %>

Related

How to redirect_to(:back) two times?

def update
if #note.update_attributes(note_params)
redirect_to :back, notice: "Note was updated."
else
render :edit
end
end
Is there a way to redirect back twice?
Here you go:
This is where the link for editing goes:
<p id="notice"><%= notice %></p>
<% url = "#{request.protocol}#{request.host_with_port}#{request.fullpath}" %>
<%= link_to 'Create New Page and Return Here', edit_page_path(1, :url => Base64.encode64(url) ) %>
<br>
After submit your url will be something like this:
http://localhost:3000/pages/1/edit?url=aHR0cDovL2xvY2FsaG9zdDozMDAwL2R1bW1pZXM%3D%0A
In the edit form:
I called it pages/_form.html.erb, Pass the URL as a hidden params.
<%= form_for(#page) do |f| %>
<% if #page.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#page.errors.count, "error") %> prohibited this page from being saved:</h2>
<ul>
<% #page.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :permalink %><br>
<%= f.text_field :permalink %>
</div>
<%= hidden_field_tag :url, params[:url].to_s %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
In controller that you have update method, in this case pages_controller.rb, simply Base64 it back and redirect the user:
def update
redirection = nil
if params[:url].present?
redirection = Base64.decode64(params[:url].to_s)
end
if #page.update(page_params)
if redirection.present?
path = redirection
else
path = #page
end
redirect_to path, notice: 'All Done.'
else
render :edit
end
end
Now user updates the form and redirected back to the first show or index page or any page that she is coming from.
Hope this help.
PS: You might want to clean it up a bit and pass the url from the controller, and put some checks on it. So you don't define any var at the view level. In the above code I just tried to solve this issue not really a design pattern oriented :)

Edit and update issue

New and Create are working good, data is stored in the database but edit and update is having issues.
This is my sages controller sages_controller.rb
class SagesController < ApplicationController
def home
end
def about
end
def new
#sage = Sage.new
end
def create
#sage= Sage.new(sage_params)
if #sage.save
flash[:success] = 'Thanks for Joining'
redirect_to '/thanks'
else
flash[:notice] = 'Please fill the form Correctly'
render 'new'
end
end
def edit
#sage=Sage.find(params[:id])
end
def update
#sage = Sage.find(params[:sage])
if #sage.update_attributes(sage_params)
redirect_to '/thankss'
else
render 'new'
end
end
def resources
end
private
def sage_params
params.require(:sage).permit(:Name, :Email, :Address, :Number)
end
end
THis is my view for new method new.html.erb
<div class="contact" style="padding: 50px; color: orange ">
<%= form_for #sage do |f| %>
<div class="form-group" >
<h3><%= f.label :Name%></h3>
<%= f.text_field :Name %>
<br/>
</div>
<div class="form-group" >
<h3><%= f.label :Email%></h3>
<%= f.email_field :Email %>
</div>
<div class="form-group" >
<h3><%= f.label :Address%></h3>
<%= f.text_field :Address %>
<br/>
</div>
<div class="form-group" >
<h3> <%= f.label :Number%></h3>
<%= f.number_field :Number %>
<br/>
</div>
<br/>
<br/>
<div class="submit" >
<h2><%= f.submit 'SUBMIT'%></h2>
</div>
<% end %>
<%= link_to 'Edit', 'edit' %>
</div>
`
This is my view for Edit method edit.html.erb
<%= form_for #sage do |f| %>
<%= f.label :Name %>
<%= f.text_field :Name %>
<br/>
<%= f.label :Email %>
<%= f.text_field :Email %>
<br/>
<%= f.label :Address %>
<%= f.text_field :Address %>
<br/>
<%= f.label :Number %>
<%= f.text_field :Number %>
<br/>
<%= f.submit 'Update' %>
<% end %>
`
This is my routes in routes.rb
resources :sages,only: [:new,:create,:edit, :update]
get 'sages/home'=>'sages#home'
get 'sages/about'=>'sages#about'
get 'sages/resources'=>'sages#resources' `
You are doing it wrong, how can you edit a record if it doesn't exist. In new.html.erb you have added a link
<%= link_to 'Edit', 'edit' %>
Remove that line, its wrong. You can only edit an existing record and not a new record. Also, the route is wrong. It should look something like
<%= link_to 'Edit', edit_sage_path(#sage) %>
Hope this helped!
Which URL or path you are using? I imagine you are using an incorrect URL or path.
With the routes you mentioned you should have the following access route for edit:
edit_sage GET /sages/:id/edit(.:format) sages#edit
So either you use edit_sage(id) or you type in the URL with /sages/id/edit. Please note that you have to replace id (in path or URL) by a valid id of a sage.
In the new view you cannot edit an object that does not exist (i.e. is not persisted in database).
<%= link_to 'Edit', 'edit' %>
is wrong as mentioned by other users.
Also if ever you want to call edit, consider what I mentioned in the beginning. Make sure you pass a valid id or sage object that effectively exists in database.
First thing you need to change edit link, it should be like :
<%= link_to 'Edit', edit_sage_path(#sage) %>
Second thing you can't call edit link in your new template because in this case you have #sage is empty (it just initiated),you can edit your sage by adding 'Edit' link to either index or show template
in update action change
def update
#sage = Sage.find(params[:id])
if #sage.update_attributes(sage_params)
redirect to ('/thanks')
else
render 'new'
end
end
Like an example if you have record with id = 2 then write url like /sages/2/edit and you will get data with record id=2.
Do this below change in your update method also,
#sage = Sage.find_by_id(params[:id])
The link i gave was wrong for edit in new.html.erb, removed it
and changed the route of edit to:
get 'sages/id/edit'=>'sages#edit' in routes.rb and now it works fine....

How do I display validation errors with namespaces? Ruby on rails

I can't figure out how to do this.. I'm in the user-controller that's inside a namespace called admin, and this is how my form looks like:
<%= form_for [:admin, #user] do |f| %>
<% if #user.errors.any? %>
<div class="reg-error">
<h4>Could not send registration!</h4>
<ul>
<% for message in #user.errors.full_messages %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.label :email %><br>
<%= f.text_field :email %><br><br>
<%= f.label :rank %><br>
<%= f.select :rank, options_for_select([1, 2, 3, 4, 5]) %><br><br>
<%= f.submit "Send registration", :confirm => "Are you sure?" %>
<% end %>
As you can see I'm using [:admin, #user] for the form, but it doesn't work with just replacing #user.errors.any? with [:admin, #user].errors.any?
The form it self works just fine, but it just won't display the validation errors.
How do I do this?
UPDATE - SOLVED
I didn't show you my controller, and I found the error there..
if #user.save
UserMailer.invitation_mail(#user).deliver
redirect_to admin_manage_users_path, :notice => "Successfully added a new account! Mail has been sent"
else
#user = User.new
#registered_users = User.where(:reg_key => nil)
#pending_users = User.where("users.reg_key IS NOT NULL")
render "show"
end
Since I had a #user = User.new in the else statement, It resetted the error messages some how. Totally missed that one. I'll leave it here if someone else would do this simple mistake too.. Thanks for the replys tho.
Try making just the following changes:
form_for #user do |f|
if #user.errors.any?
...
#user.errors_full_messages.each do |message|
<li><%= message %></li>
If that doesn't work can you show me what your controller looks like. For instance, in your users_controller new method are you doing something like:
#user = Admin::User.new

Rails - Couldn't find User with id=edit

I am using Rails 3 and Devise for authentication. When I try to update my current_user, an exception is thrown stating:
Couldn't find User with id=edit
app/controllers/users_controller.rb:49:in `update'
Here is update and edit in UsersController:
#UsersController.rb
def update
#user = User.find(params[:id])
respond_to do |format|
if #user.update_attributes(params[:user])
format.html { redirect_to #user, notice: 'User was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
def edit
#user = User.find(params[:id])
end
And here is /views/layouts/_navigation.html.erb:
<%= link_to "Home", root_path, :class => 'brand' %>
<ul class="nav">
<% if user_signed_in? %>
<li>
<%= link_to('Logout', destroy_user_session_path, :method=>'delete') %>
</li>
<% else %>
<li>
<%= link_to('Login', new_user_session_path) %>
</li>
<% end %>
<li>
<%= link_to('About', help_about_path) %>
</li>
<% if user_signed_in? %>
<li>
<%= link_to('Edit Account', edit_user_path(current_user)) %>
</li>
<% end %>
<% if user_signed_in? and current_user.role == "gen_admin" || current_user.role == "teacher" %>
<li>
<%= link_to('View Students', users_path ) %>
</li>
<% end %>
<% if user_signed_in? and current_user.role == "gen_admin" || current_user.role == "teacher" %>
<li>
<%= link_to('New User', new_user_path ) %>
</li>
<% end %>
<% if user_signed_in? %>
<li>
<%= link_to('Student Data', data_path) %>
</li>
<% end %>
</ul>
Finally, here is /views/devise/registrations/edit.html.erb:
<h2>Edit <%= resource_name.to_s.humanize %></h2>
<%= form_for(resource, :as => resource_name, :url => edit_user_registration_path(resource_name), :html => { :method => :put }) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :email %><br />
<%= f.email_field :email, :autofocus => true %></div>
<div><%= f.label :teacher %><br />
<%= f.text_field :teacher %></div>
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
<% end %>
<div><%= f.label :new_password %> <i>(leave blank if you don't want to change it)</i><br />
<%= f.password_field :password, :autocomplete => "off" %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></div>
<div><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password %></div>
<div><%= f.submit "Update" %></div>
<% end %>
<%= link_to "Back", :back %>
Why is the user id=edit? Here is my hash, if that helps:
{"utf8"=>"✓",
"_method"=>"put",
"authenticity_token"=>"7g1WsNCVuNY/5ZTeBUdv97tbdAPacvvDAzBSMGCcuNY=",
"user"=>{"email"=>"email#admin.com",
"teacher"=>"Demont",
"password"=>"[FILTERED]",
"password_confirmation"=>"[FILTERED]",
"current_password"=>"[FILTERED]"},
"commit"=>"Update",
"id"=>"edit",
"format"=>"user"}
Try using:
#user = current_user
Something looks to be wrong with your route or edit form. Try using the form like in their wiki page...
https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-edit-their-password
But the above code should get around this
Most likely you I've got conflict in your routes when added UsersController.
There is devise's wiki page explaining that.
Default devise's route for edit user is /users/edit but in your controller path for update action is /users/:id. What's why you've got "edit" instead of user_id
Use
<%= form_for(#resource, :as => resource_name, :url => edit_user_registration_path(resource_name), :html => { :method => :put }) do |f| %>
to your form view and
#resource = User.find(params[:id])
in your edit action.

i have a form to create new users, but dont work

i have a problem with a form to create a user... this is my code of "new"
<%= form_for #user do |f| %>
<% if #user.errors.any? %>
<% for message in #user.errors.full_messages %>
<div class="alert">
<button type="button" class="close" data-dismiss="alert">×</button>
<%= message %>
</div>
<% end %>
<% end %>
<div class="field">
<%= f.label :username %>
<%= f.text_field :username %>
</div>
<div class="field">
<%= f.label :email %>
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :password %>
<%= f.password_field :password %>
</div>
<div class="field">
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %>
</div>
<div class="actions"><%= f.submit "Registrarse" %></div>
<% end %>
and "create" in controller
def create
#user = User.new(params[user])
if #user.save
redirect_back_or_to root_url, :notice => "Usuario Registrado Satisfactoriamente!"
else
render :new, :notice => "No se ha podido registrar"
end
end
when i create the user, this go to login form, and a receive a message empty, because i have an "if" if i have message, this show me a div with some css, so i can see that an error ocurred, but this come empty, what i have wrong? i dont see anything... and of course, the user is not created.!
thanks for the help, i am a newbie in ruby. and sorry for my bad english xd
The problem is that you most likely are referencing password_confirmation which is usually an input tag. You most likely do not have this field in your database as it would just be horrible practice. Are you salting your passwords?
Check out sorcery on github and the Railscasts. It does a nice job on covering authentication.
Also, you need to use :user in the params => User.new(params[:user])

Resources