Rails - Trouble Using Ajax on Like Action - ruby-on-rails

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

Related

model validation errors not rendered with render :action => "index"

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

Ruby on Rails new objects in partial identifier stops at 1

I have Article(s), that has_many ArticleAssets. Fairly simple. On the edit form for the Article I just want to add new article assets. I don't need to edit the current ones, so I created a partial like this:
<% f.fields_for :article_assets, article_asset do |builder| -%>
<div class="article_asset">
<%= builder.file_field :image %>
<%= builder.check_box :is_flagged, :class => "isFlagged" %> isFlagged
</div>
<% end -%>
No collection, because I only need one object at a time and need no data from the existing article assets. In the form of edit.erb I render the following:
<%= render :partial => 'article_asset', :locals => {:f => f}, :object => ArticleAsset.new %>
This makes one new article asset show up that I can add information to, all cool so far. Important is that this field gets the name-form of article[article_assets_attributes][0][is_flagged]. All good since this will also group the hidden field that always comes with a checkbox in rails to the rest of the fields. Then I have an "Add item" link that does this:
page.insert_html :bottom, :article_assets_fields, :partial => "article_asset", :locals => {:f => f}, :object => ArticleAsset.new
Clicking on this link gives a new field under the created one, as expected, with the name-form of the checkbox field of article[article_assets_attributes][1][is_flagged]. Incremented, that's perfect! Adding another one with the same link however, also gives the same form (also with the identifier of 1, duplicate), which makes submitting the form only have 2 items instead of 3. Does anyone know why this happens and what I can do to solve it?
Ruby on Rails 2.3.11
Nested form 2.3 fail. This one was the bane of my existence for some time, even having watched the railscast etc. Here's my how to:
1) this goes in article.rb
after_update :save_article_assets
def new_article_asset_attributes=(article_asset_attributes)
article_asset_attributes.each do |attributes|
article_assets.build(attributes)
end
end
def existing_article_asset_attributes=(article_asset_attributes)
article_assets.reject(&:new_record?).each do |article_asset|
attributes = article_asset_attributes[article_asset.id.to_s]
if attributes
article_asset.attributes = attributes
else
article_assets.delete(article_asset)
end
end
end
def save_article_assets
article_assets.each do |article_asset|
article_asset.save(false)
end
end
2) In a helper somewhere:
def add_article_asset_link(name)
button_to_function name, :class => "new_green_btn" do |page|
page.insert_html :bottom, :article_assets, :partial => "article_asset", :object => ArticleAsset.new()
end
end
def fields_for_article_asset(article_asset, &block)
prefix = article_asset.new_record? ? 'new' : 'existing'
fields_for("article[#{prefix}_article_asset_attributes][]", article_asset, &block)
end
3) in your partial:
<% fields_for_article_asset(article_asset) do |aa| %>
<tr class="article_asset">
<td><%= aa.text_field :foo %></td>
<td><%= link_to_function "remove", "$(this).up('.article_asset').remove()" %></td>
</tr>
<% end %>
4) in the _form:
<table>
<%= render :partial => "article_asset", :collection => #article.article_assets %>
</table>
<%= add_article_asset_link "Add asset" %>

Chosen plugin not detected because of ajax call for form partial?

I'm not sure why the Chosen Plugin is not being called when my form partial is dynamically called.
Relative Gems -
rails, 3.1.0
cancan, 1.6.7
dynamic_form, 1.1.4
simple_form, 2.0.1
jquery-rails
Scenario -
I have a page called /index and you can add a House, Dog or Cat. The page starts out blank but has links on the side that you can click to dynamically bring up one of the forms. These forms are in a their own partials.
DogsController
def new
#dog = Dog.new
respond_to do |format|
format.js
end
end
dogs/_form.html.erb
<%= simple_form_for(#dog, :remote => true, :html => { :class => 'form-horizontal span8' }) do |f| %>
<%= render :partial => "shared/error_message", :locals => { :f => f } %>
<%= f.association :house, :prompt => "Select a House", :input_html => { :id => "house-select", :class => "span4" } %>
<%= f.button :submit, 'Done', :class => 'btn-primary span2' %>
<% end %>
PagesController
def index
#cats = current_user.cats.all
#dogs = current_user.dogs.all
respond_to do |format|
format.html
end
end
pages/index.html.erb
<li><%= link_to "Dog", new_dog_path, :remote => true %></li>
<li><%= link_to "Cat", new_cat_path, :remote => true %></li>
<div id="generate-form">
<div class="ajax-loader"></div>
</div>
dogs/new.js.erb
$("#generate-form").html("<%= escape_javascript(render(:partial => 'dogs/form', locals: { dog: #dog })) %>");
All of this code successfully brings up the chosen form on a link click.
My dog model is the same as the cat one. These are the ones with the Chosen plugin issue. Now why isn't the Chosen plugin detected when either form is brought up?
Answer
dogs/new.js.erb
$("#generate-form").html("<%= escape_javascript(render(:partial => 'dogs/form', locals: { dog: #dog })) %>");
$('.house-select').chosen();
I don't see any call to the chosen plugin in your code sample, but I've had the same issue.
The initial call to $('.chzn-select').chosen() will apply to all DOM elements that are on the page at the time, but not to elements that get added later.
To add the plugin to the new .house-select elements that are inserted via AJAX, add this to the end of dogs/new.js.erb:
$('#generate-form .house-select').chosen();
It's worth noting that you can safely run the jQuery .chosen() function on a select box more than once. It adds its own css classes to track which ones have had chosen applied and will gracefully ignore them on consecutive runs.

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.

RoR: Replace_html with partial and collection not functioning

I am trying to create a tabbed interface using the prototype helper method "replace_html." I have three different partials I am working with. The first one is the 'main tab' and it is loaded automatically like so:
<div id = "grid">
<% things_today = things.find_things_today %>
<%= render :partial => "/todaything", :collection => things_today, :as =>:thing %>
</div>
...which works fine. Similarly, I have a _tomorrowthing partial which would replace the content in the 'grid' div like so:
<%things_tomorrow = things.find_things_tomorrow%>
<%= link_to_function('Tomorrow',nil, :id=>'tab') do |page|
page.replace_html 'grid' , :partial => '/tomorrowthing',:collection => things_tomorrow, :as => :thing
end %>
If I click on this tab nothing happens at all. Using firebug, the only errors I find are a missing ) after argument list which is contained in the Element.update block where the link_to_function is called. What am I doing wrong?
Hey Jack i try to reproduce the same but i can't i never used link_to_function before but
Following code may help to achieve the same you want
<%= link_to_remote "Today Thing", :url=>{:action=>"things", :id=>'today'}%>
<%= link_to_remote "Tomorrow Thing", :url=>{:action=>"things", :id=>'tomorrow'}%>
<div id = "grid">
<% #things = things.find_things_today %>
<%= render :partial => "/todaything", :collection => #things %>
</div>
in controller
def things
#things= (params[:id]=="today")? things.find_things_today : things.find_things_tomorrow
render :update do |page|
page.replace_html 'grid', :partial => (params[:id]=="today")? "/todaything" : '/tomorrowthing' , :objects=> #things
end

Resources