5

I use some code working nicely on Rails 3 but not on Rails 4, I guess it is caused by Turbolinks but I don't know much about it, can't dig more deep to solve my problem, here is the code:

view:

a/v/m/_new_comment.slim                                                                                                                             
.new-comment                                                                                                                                         
- if current_user
  = render "editor_toolbar"
  = form_for(Comment.new, :remote => true, :url => mission_comments_path(@mission)) do |f|
  = f.text_area :content, :class => "span10",
    :rows => "4", :tabindex => "1"
  #preview.hidden
    = "Loading..." 
  = f.submit t("missions.submit_comment"),
    "data-disable-with" => t("missions.submitting"),
    :class => "btn btn-primary", :tabindex => "2"
- else
  = render "need_login_to_comment"

controller:

def create
  @mission = Mission.find(params[:mission_id])
  @comment = @mission.comments.build(comment_params)
  @comment.user = current_user

  if @comment.save
  @mission.events.create(user: current_user, action: "comment")
  render layout: false
end

and js:

<% if @comment.errors.any? %>                                                                                                                        
  $(".new-comment textarea").focus();
<% else %>
  $(".comments").append("<%= j (render @comment, :index => @mission.comments.count-1) %>");
  $(".new-comment #preview").addClass("hidden").html('');
  $(".new-comment textarea").css("display", "block").val('');
  $(".editor-toolbar .preview").removeClass("active");
  $(".editor-toolbar .edit").addClass("active");
<% end %>

I have two question about this code, first: the controller code like this isn't work the js code is transfer to client but not run, I have to add render layout: false at bottom of that action, no need this on Rails 3

second question: when I first visit this page, reload the page, comment function works, but if I click a link from other pages to jump to this page, I submit this form will cause ajax request call multiple times, multiple comments will be created

thanks in advs

William Herry
  • 1,430
  • 14
  • 26
  • I can't comment on your specific code, but you can try removing turbo-links and seeing if it works without. [Instructions to remove turbolinks](http://blog.steveklabnik.com/posts/2013-06-25-removing-turbolinks-from-rails-4) – Althaf Hameez Aug 06 '13 at 00:28
  • just remove turbolinks from application.js file make it works – William Herry Aug 06 '13 at 00:44

3 Answers3

16

Solved this by moving = javascript_include_tag "application", "data-turbolinks-track" => true from body to head, thanks all your help

idmean
  • 14,540
  • 9
  • 54
  • 83
William Herry
  • 1,430
  • 14
  • 26
  • 4
    Thanks for advice! Helps me alot, cannot figure it out what's the problem for an hour! Really should be somewhere in documentation, it's common recommendation to move scripts right before –  Sep 21 '13 at 15:54
10

You can leave it in the body, you just need to add to your script tag:

"data-turbolinks-eval" => false

In general, with turbolinks, it's best to make sure your code is "idempotent", so if it runs more than once, bindings won't get setup more than once.

The best way to do this is instead of $('blah').bind(), call unbind first:

 $('blah').unbind('click').bind('click', function() {
Kevin
  • 4,225
  • 2
  • 37
  • 40
  • Yeah. There are some complicated plugins to try and solve it instead, but I've found unbind() much simpler and more effective, though it does add some ugly! – Kevin Sep 19 '13 at 05:20
  • 1
    Rather than unbinding and binding again, it’d be better to do `$(document).on('click', '.blah', function(e) {});`. – Jezen Thomas Dec 02 '14 at 21:34
1

One possible reason you could be running into issues is if you are including the js on every page. It's my understanding it will append the js to the head and if you have included it on multiple pages you could find yourself binding the ajax multiple times. That being said it's not apparent how you are including the js from what I saw. You could possibly solve this by only including the js file in your application.js

Micharch54
  • 576
  • 1
  • 7
  • 15
  • I only include js file in application, so I think this may not the reason, by the way, the view code up there is included as a partial, does this may be the reason? – William Herry Aug 06 '13 at 06:18