model validation errors not rendered with render :action => "index" - ruby-on-rails

I am working on a simple youtube list app where the user can add videos to the list. I am validating for the presence of the video_id field.
class Track < ActiveRecord::Base
attr_accessible :title, :thumbnail_url, :video_id
validates :video_id, :presence => true
end
i have the following create function defined in my controller:
def create
#fetches the video info, stores it in #trackinfo
if is_url(params[:track][:query])
#trackinfo = getTrackInfo(params[:track][:query])
else
#trackinfo = youTubeQuery(params[:track][:query])
end
#use #trackinfo to create track object
#track = Track.new(#trackinfo)
#tracks = Track.all
#video_ids = Track.pluck(:video_id)
if #track.save
else
render :action=>"index"
end
end
in my index.erb.html i have the following block:
<%= render partial: "error_message" %>
the corresponding _error_message.erb.html just contains the error messages from the validation:
<% if #track.errors.any? %>
<% #track.errors.full_messages.each do |msg| %>
<%= msg %><br>
<% end %>
<% end %>
the problem is when the validation fails, i am not able to see the error message from the rendered view. I logged the messages right before it entered the render index, and was able to see the messages:
from the controller:
if #track.save
else
puts "#{#track.errors.full_messages}" #i am able to see this
render :action=>"index"
end
i dont know what happens during the render causing the error messages not to be displayed, on the server logs it does say that the _error_messages.erb.html has been rendered, but i just dont see anything happen to the page. I feel like i have missed something really obvious. anyone knows what i should do?
Thanks

i think i resolved this issue, but im not sure if my fix is proper. I forgot to mention that on the main index.erb.html i have a search bar and a submit buttom embedded in an ajax form that calls the create function inside the controller
<%= form_tag(#track, :remote=>true, :method => :post, :class => 'new_track') do %>
<%= text_field_tag "track_query", nil, :placeholder => 'enter a query or a link', :id => "search_bar", :name => "track[query]", :size => 30, :required => true %>
<%= submit_tag "add" , :name => 'commit'%>
</p>
<% end %>
i also now have the error div in the same page (I deleted the render partial and just stuck an empty div to be populated in the index.erb.html):
<div id = "error_message">
</div>
in the file create.js.erb, I added the following lines:
<% elsif #track.errors.any? %>
if($.trim($("#error_message").html())==''){
<% #track.errors.full_messages.each do |msg| %>
$('#error_message').hide().append('<%= msg %>');
<% end %>
$('#error_message').fadeIn();
}
$('#search_bar').val('');
it seems that when i remove the render :action=>"index" completely from my create function in the controller, the error messages were able to be displayed on the index page. I was hoping to not put so much processing on the client javascript side and more on the controller side. Is there another way to do this? Still wondering why the render did not render that partial html. is it because the form is ajax and wont render the whole page? i apologize if i dont exactly know what im talking about :)

Related

Rails - Trouble Using Ajax on Like Action

I'm having a little trouble with using AJAX on something I've done before with no issues, but this site has a few different configurations which are causing trouble for me. The main problem I'm having, is when I click the Like link on a post, all of the like links on that page are changed to unlike, even though the one I clicked is the only one getting posted in the Database.
On my user's profile page (users/show.html.erb), I'm showing all of the posts (updates in this scenario) that the particular user has posted.
Here is my configuration thus far:
Users Controller, Show Action
def show
#updates = #user.updates.paginate(:page => params[:page], :per_page => 20)
end
Updates Controller, Like Action
def like
begin
#vote = current_user.vote_for(#update = Update.find(params[:id]))
if #vote.save
respond_with #update.user, :location => profile_path(#update.user)
end
rescue ActiveRecord::RecordInvalid
redirect_to #update
end
end
users/show.html.erb
<div class="like_button">
<%= render :partial => 'updates/like_button', :locals => {:update => update} %>
</div>
updates/_like_button.html.erb Partial
<% if current_user.voted_on?(update) %>
<%= link_to unlike_update_path(update), :method => :post, :remote => true do %>
<i class="ss-heart liked" title="Unlike Update"></i>
<% end %>
<% else %>
<%= link_to like_update_path(update), :method => :post, :remote => true do %>
<i class="ss-heart animate" title="Like Update"></i>
<% end %>
<% end %>
updates/like.js.coffee
$(".like_button").html("<%= escape_javascript render :partial => 'updates/like_button', :locals => {:update => #update} %>");
So just to refresh, the like button works and records the vote into the database, but it changes all of the like_buttons on the page to appear as if they have been liked instead of just the one post.
You need some way to distinguish your like buttons (by css class / id for example) and then you can alter them with jQuery concretely
$(".like_button").html("<%= escape_javas...
while currently $(".like_button") aims for all elements with that .like_button class (which are all).

Ajax form within a form with no layout

So I'm new to rails and having a little bit of trouble my situation is that I have a products model that has some Images attached to it. I would like on my products page to have a button to create a new image via ajax.
Inside my products _form view i have:
<%= simple_form_for(#product) do |f| %>
<%= f.error_notification %>
<div class="inputs">
<%= f.input :name %>
<%= f.input :description, :input_html => {:class => "wysihtml5 span6", :style => "height:400px;"} %>
<%= f.association :images, label_method: :name, value_method: :id %>
<h4>Upload new file</h4>
</div>
<%= link_to 'Add Image', '/images/new', :remote => true, :"data-replace" => "#image-form" %>
<div id="image-form">
</div>
<div class="actions">
<%= f.button :submit %>
</div>
<% end %>
And it does successfully Load the page via ajax.
But I would like to load it without the layout. Is this possible?
Do I need to create a new action that renders the partial form and has no layout??
So I'm assuming you have it requesting and returning html and not js? There are a couple of thoughts I have on this:
If you only ever need for this request to return from an AJAX request, then you could simply tell the controller to always render layout: false
If you would like to allow the controller to return a full page on occasion, you can either accept an argument in the get request and change the output accordingly, or you can tell the controller to:
respond_to do |format|
format.html # will render default with no block passed
format.js { render layout: false }
end
This should just work with the code in your form right now, because the :remote => true tells the controller to return js if possible, but accessing images/new from your browser will request html.
(Requesting js does not mean that you actually have to return js, as I don't in this case; it's up to you to take the proper action with what is returned. Some might consider it bad form, though, to return something other than what is technically requested.)
You can use the following in your action. Let your action is new.
def new
#your code goes here
render :layout => false
end

Unable to display text from Rails ActiveRecord errors.full_message

Ok, I've looked over results for this off and on all day (including search all over StackOverflow)...
In Rails 3.2.X and Ruby 1.9.3 I have a remote form. The form is working correctly and saving when valid, and not saving when not valid. However I can't get back the actual errors (and I've tried a bunch of different ways).
Here's the form (haml)
= form_for #lead, :remote => true, :validate => false do |f|
.span6
%ul
%li
= f.label "Name*"
= f.text_field :name
%li
= f.label "Company*"
= f.text_field :company
...
%li
= f.label :state
= select_tag :state, options_for_select(us_states)
%li
= f.label "Email*"
= f.text_field :email
.actions
= f.submit '', :id => "contactsubmit"
Here's the relevant spot in the controller:
def create
#lead = Lead.new(params[:lead])
respond_to do |format|
if #lead.valid?
format.js
else
format.js
end
end
end
And here's my view (create.js.erb) where I keep failing...
<% if #lead.errors.count == 0 %>
$('#error_explanation').fadeOut(500);
$('#learn-more .form').fadeOut(500, function() {
$('#learn-more #form-response').fadeIn(500);
});
<% else %>
$('#error_explanation').fadeIn(500);
<% #lead.errors.full_messages.each do |msg| %>
#never shows any messages. If I do #lead.errors.each do |error|
#it shows the field name, but not the body...?
$('#error_explanation').append('<%=content_tag(:p, msg)%>');
<% end %>
<% end %>
I know that commment isn't valid in there, I added it to show what I've tried.
I've tried a million different ways of showing the error message here. Everything else is working. I even added a counter in there (when not using msg) and it did show the four field errors. Any advice? Using similar code in another project (in a traditional view) w/o problem.
Make sure you're using escape_javascript anytime you run into troubles like this. Any quotes that might be inside the content or generated by a method like content_tag can break your JS.

Handling an undefined variable

I render a partial in one view:
<%= render 'video', :video => #video, :video_id => 'video_show_id' %>
and have this code in the partial:
<% if video_id %>
<%= link_to "video", video.video_url, :class => "oembed", :id => video_id %>
<% else %>
<%= link_to "video", video.video_url, :class => "oembed" %>
<% end %>
The problem is that this partial gets rendered in a number of places in my app, and in those other views I do not want to pass :video_id into the partial. Therefore my app throws an error that video_id is undefined. I could pass :video_id => "" into the partial in the other views, but since the partial is rendered in many places, that is kind of a pain. Is there a simpler way to handle this?
Try defined? and not that it really matters but it's actually an operator.
<% if defined? video_id %>
I think the better way to handle this is to create a helper that then manages the values of variables that need to fed to a partial. Something like:
module VideoHelper
def show_video(video, options = {})
options[:id] ||= ""
render 'video', :video => video, :video_id => options[:id]
end
end
Now, instead of having to have that long render partial line in your view, you get to shorten it to a show_video call.
Also, I've found that in the long term, this allows for a lot more flexibility and I have to think a lot less about what variables the partial needs at this time and whether or not they are defined.
Change the check to <% if defined? video_id %>

How to make the page not redirect in Rails

I have an erb file named index that has a form in it. As a simple example:
<% form_for #foo, :url => {:action => 'bar'} do |f| %>
<%= f.submit "BAR!" %>
<%end%>
When I click the BAR! button it preforms the actions I expect and it forwards me onto the bar.erb file, displaying the expected output. What I would like to be able to do, however, is to take the generated html from this page and stuff it into the innerHTML of a div on the index page. I assume there is a way but I must ask, is there a way to achieve this? Are there any examples available that would be helpful? Thanks!
You should be able to pass the id of the div to update like so:
<% remote_form_for #foo, :url => {:action => 'bar'}, :update => 'id-of-div-to-update' do |f| %>
<%= f.submit "BAR!" %>
<%end%>
In the controller:
def bar
# your code here
respond_to do |format|
format.html { redirect_to(xxx) }
format.js
end
end
Rails will look for a template named bar.js and will render it and return it's content to the browser without a redirect.

Resources