How do I display validation errors with namespaces? Ruby on rails - 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

Related

Ruby On Rails - creating an object does not respect validations and showing error messages

I'm having troubles handling objects that not respect the validation.
I'm building an app in which an user can create a "Trip" model and then add steps to his trip, that I called "Traces". Each added trace prints a new part of a map present in the trip#show action.
The association between models is user has_many trips and trip has_many traces
In the users#show I put a "CREATE NEW TRIP" button linking to the trips#new and here I have the form_for with the field corresponding to the Trip attributes.
When I fill the form correctly everything is ok. When something is missing or wrong (for the validations) I get this error:
NoMethodError in Trips#create
undefined method `model_name' for Array:Class
------ in the trips_controller.rb
def create
#trip = current_user.trips.build(params[:trip])
if #trip.save
# handle a successful save
flash[:success] = 'Trip created!'
redirect_to user_trip_path(#trip, user_id: current_user.id)
else
#trip = []
#feed_items = []
render 'new'
end
end
------ in app/views/trip, in the new.html.erb
h1>Create a trip</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3 general-input">
<%= form_for ([current_user, #trip]) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :name,'Give a name to your trip ;)' %>
<%= f.text_field :name %>
<%= f.label :trip_start, 'Choose your starting point!' %>
<%= f.text_field :trip_start %>
<%= f.label :departure, 'When are you leaving?' %>
<%= f.date_select :departure, :start_year => Date.current.year %>
<%= f.label :arrive, 'And coming back home?' %>
<%= f.date_select :arrive, :start_year => Date.current.year %>
<%= f.submit 'Create a new trip', class: 'btn btn-primary btn-lg' %>
<% end %>
EDIT 1: problem solving removing #trace=[ ] from trips_controller.rb
EDIT 2:
I also have a similar problem with the creation of a new Trace:
The form for adding a new trace is in the trip#show page.
When I try to create a trace that not respects the validation (e.g. if I leave blank the "destination" field) I get this error:
NoMethodError in Posts#create
undefined method `any?' for nil:NilClass
When I'm on the Trip page where the form for the Traces is placed, the URL is like:
http://localhost:3000/users/2/trips/8
but when I create a not valide Trace it switchs to a path like:
http://localhost:3000/trips/8/posts
I suppose I'm doing something wrong handling the error messages. I probably misunderstood something, even because I'm new to Rails and web programming in general.
Here you are some code parts, hoping it helps to understand my mistake:
------ in the traces_controller.rb
def create
#trip= Trip.find(params[:trip_id])
#trace = #trip.traces.create(params[:trace])
if #trace.save
flash[:success] = 'Trace created!'
redirect_to user_trip_path(#trip, user_id: current_user.id)
else
#trace=[]
render 'trips/show'
end
end
------ in app/views/shared, in the add_trace_form.html.erb
<p>Complete your trip adding a route!</p>
<%= form_for ([#trip, #trip.traces.build]) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="block post-form">
<div class="field ">
<%= f.text_field :end, placeholder: 'Where are you going next?' %>
<%= f.label :arr_day, 'When?' %>
<%= f.date_select :arr_day, :start_year => Date.current.year %>
<%= f.submit 'Add route', class: 'btn btn-primary btn-landing' %>
</div>
</div>
<% end %>
------ in app/views/shared, in the error_messages.html.erb
<% if object.errors.any? %>
<div id="error_explanation">
<div class="alert alert-error">
The form contains <%= pluralize(object.errors.count, "error") %>.
</div>
<ul>
<% object.errors.full_messages.each do |message| %>
<li>* <%= message %></li>
<% end %>
</ul>
</div>
<% end %>
------ in the routes.rb
resources :users do
resources :trips
end
resources :trips do
resources :traces
end
resources :traces
Thanks a lot
i think when you are passing the f.object in locales in render its is passing array not the active record object ,<%= render 'shared/error_messages', object: f.object %>.
Can u check inspecting object in your partial and what class it has.
Try inspecting object.errors.inspect
Try refering http://guides.rubyonrails.org/layouts_and_rendering.html#using-partials

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 :)

Comments form showing blank comments even when database is empty, rails

I'm building a comments section on my blog, and so far I have it working to the point where I can successfully submit comments and have them appear on my page.
However, there is always a blank comment on the page whether I have 10 comments or the database is empty.
*** views/artist/lyrics/show.html.erb ***
<%= form_for(#lyric.comments.build, url: artist_album_lyric_comments_path(#artist, #album, #lyric)) do |f| %>
<%= f.text_area :content %>
<%= f.submit "comment" %>
<% end %>
<% if #lyric.comments.any? %>
<% #lyric.comments.each do |comment| %>
<%= comment.username %>
<%= comment.content %>
<% end %>
<% else %>
No one has commented.
<% end %>
*** /controllers/users/comments_controller.rb ***
def create
#comment = Comment.new(comment_params)
#comment.user_id = current_user.id
#comment.username = current_user.username
#comment.lyric_id = Lyric.friendly.find(params[:lyric_id]).id
if #comment.save
redirect_to (:back)
else
redirect_to root_url
end
end
The Comment model is nested and I think that has something to do with it. It's Artist => Album => Lyric => Comment
When I remove the Comment form from the page the blank comment disappears and the <else> statement runs.
In your form_for tag, you are building a comment on #lyric. I believe this is showing up when you are calling #lyric.comments immediately after. Try:
<% #lyric.comments[0..-2].each do |comment| %>
That will grab all the comments from the first to the second to last (basically all of them except the new one you just created).
Edit:
Also change <% if #lyric.comments.any? %> to <% if #lyric.comments.any? && !#lyric.comments[0].new_record? %>
I used this on my code before. Try this:
<% #lyric.comments.each do |comment| %>
<% next if comment.new_record? %>
<%= comment.username %>
<%= comment.content %>
<% end %>
I changed this line:
<%= form_for(#lyric.comments.build, url: artist_album_lyric_comments_path(#artist, #album, #lyric)) do |f| %>
to:
<%= form_for(Comment.new, url: artist_album_lyric_comments_path(#artist, #album, #lyric)) do |f| %>
It runs the else statement and gets rid of the new record on the page.

Rerouting to path upon submit 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| %>

NoMethodError in UsersController#show

I'm getting the following error in my app when I visit a user profile page not signed into the app (I'm using Devise):
NoMethodError in UsersController#show
undefined method `connections' for nil:NilClass
app/controllers/users_controller.rb:19:in `show'
When I'm logged in the error goes away. I know why it's failing. I just need help coming up with the proper solution.
The error occurs on this line in my users controller:
def show
#connection = current_user.connections.build(user_id: current_user, otheruser_id: #user)
end
A connection form appears for users logged into the app (simply put, a button appears that asks if you would like to connect with this person as a friend). However, I'm checking if the user is logged in on the user view "show" page with <% if user_signed_in? %> before the form.
Here's the relevant code from the view:
<%= render 'connect_form' if user_signed_in? %>
connect_form
<% unless current_user == #user %>
<% if #contact.present? && user_signed_in? %>
<%= #user.first_name %> is your <%= #contact.description %> (<%= link_to "edit contact", edit_connection_path(:id => #contact.id, :user => #user) %>)<br \>
<% else %>
<% if user_signed_in? %>How do you know <%= #user.first_name %>? (<%= link_to "edit contact", new_connection_path(:user => #user) %> )
<% else %>
<% end %><br \>
<% end %>
<% end %>
connection_form (creating a new one)
<% if user_signed_in? %>
How do you know <%= #user.first_name %>?
<%= form_for(#connection) do |f| %>
<%= f.collection_select :description, Connection::CONNECTIONTYPE, :to_s, :to_s, :include_blank => true %>
<%= f.hidden_field(:otheruser_id, :value => #user.id) %>
<%= f.submit "Save", class: "btn btn-primary btn-small" %>
<% else %>
<% end %>
Why is my app trying to load a nil array `#connections even when I have the check user_signed_in? Any help is greatly appreciated!!
First thing I would do is put a check to only build the connection if the current user exist.
def show
#connection = current_user.connections.build(user_id: current_user, otheruser_id: #user) if current_user
end
The main thing to notice is the: if current_user at the end of the line
From the error message
undefined method `connections' for nil:NilClass
current_user is nil, a quickly test for this is
def show
#connection = User.new.connections.build(user_id: current_user, otheruser_id: mock_user_id)
end
For your case, maybe you didn't store the login user somewhere

Resources