Question

I've got a jQuery function that is called after a doubleclick on a list item.

app/assets/javascripts/tile/tile.js

$('#list > li').dblclick(function(){
  // styling
  $(this).toggleClass('liked');

  // pass ID to controller
  var movie_id = $(this).attr("data-id");
  $.getScript("/likes.js");
});

Next to applying some new formats to said item my main goal is to make a database entry from my like controller. In this Railscast the index action from their comments controller gets called with this simple line.

$.getScript("/comments.js");

Additionally some JavaScript gets called from a index.js.erb file.

My first problem with understanding the example code from Railscasts is how they define the action. If I wanted to call the action createLike from my likes_controller how would I call it?

Secondly, my attempts so far have all failed because both the JavaScript file doesn't load and the action doesn't get called aswell.

Somehow I sense that I've messed up with the paths. Where should I locate the JavaScript files that should get called with the getScript function?

Files

app/assets/javascripts/likes/index.js.erb

console.log("Test");

app/controllers/likes_controller.rb

class LikesController < ApplicationController
  protect_from_forgery

  def index
    Like.create(:user_id => current_user.id, :item_id => params[:id])
  end
end
Était-ce utile?

La solution

I believe the execution issue can be solved by moving index.js.erb from

app/assets/javascripts/likes/index.js.erb

to

app/views/likes

This is where Rails looks for templates to render (your script shouldn't be served by the asset pipeline). Rails tackles this through convention - your app automatically routes /likes to the index action.

If you want a more informative route, use the Rails routing guide to generate a new route and match it to the create_likes action in the Likes controller. Then, $.getScript("/create_likes.js") will know where to look

Autres conseils

You can define action in controller like that:

class LikesController < ApplicationController
  # another code
  def createLike
    # your action code
  end
  # another code
end  

And you can call action like /likes/createLike.
In the folder PATH_TO_APP/app/views/likes create a file createLike.html.erb - there is will be a createLike view

Javascript files must be in the folder /PATH_TO_APP/public/javascripts
And best way to include javascript file is a javascript_include_tag like:

<%= javascript_include_tag "tile/tile.js" %>  

tile.js file must be is into the /PATH_TO_APP/public/javascripts/tile directory.

And if you want to get javascript files with jQuery, you must put them in public/javascripts directory and call $.getScript('/javascripts/likes.js'); - there is an example.

P.S. I advise to look at getting started guide

The behavior you're wanting is different than what that specific Railscasts is addressing. It is specifically focused on the retrieving of new comments as they are created, without a page refresh. That is why you are running into issues following this guide.

First you will need to make sure you have a resources :likes in your config/routes.rb. From your code excerpt it looks like you are associating a like with a movie so make sure you make the route nested inside your resources :movies call. In the end your routes should look something like this:

resources :movies do
  resources :likes
end

For the controller piece you will need to add a 'create' action to your controller. Assuming that your Movie model has_many :likes this is a simple version of what your action should look like:

def create
  movie = Movie.find(params[:movie_id])
  movie.likes.create(user_id: current_user.id)
end

You will also need to change your javascript code to make a post instead of a get request. That's because the http method is how Rails differentiates between a create and an index request as they both use the same url path (e.g. /comments.js). You will also need to have the url reflect that it's a nested resource within a movie. Here is modified version of your JS code with that change:

$('#list > li').dblclick(function() {
  // Cached jquery this selector.
  $this = $(this)

  // pass ID to controller
  var movie_id =  $this.data('id');
  $.post('/movies/' + movie_id + '/likes.js', function() {
    $this.toggleClass('liked');
  });
});

In regards to your .js.erb file, as stated by others, it should be placed in your app/views folder. However, due to your regular JS handling the logic you don't need to have it all.

This is just one strategy but there are quite a few other ways to handle JS interaction with Rails. If you want an example of using a js.erb (js.coffee in this case) view file you can take a look at this implementation. In that case all that is handling the click event is a link_to with the remote: true option which delegates it the jquery-ujs adapter.

Hope that helps!

This might not be close to your answer but I use $.getscript() to load those js/css files that i need once my page has rendered,which in turn improves the performance and reduces the page load time.This is the code I have used in my erb files.My shop_for_free_module.js resides in app/public/javascripts

<script type="text/javascript">
    jQuery(document).ready(function($){
        //this gives your protocol-http
        var protocol = this.location.protocol;
        //this gives your domain name-myshopptinsite.com
        var host = this.location.host;
        var initial_url = protocol + "//" + host;
        $.getScript(initial_url + "/javascripts/eshop_js/shop_for_free_module.js");
    });
</script>

...hope it helps.

try this out

Question: My first problem with understanding the example code from Railscasts is how they define the action. If I wanted to call the action createLike from my likes_controller how would I call it?

Answer:

class LikesController < ApplicationController

  def create_like
    Like.create(:user_id => current_user.id, :item_id => params[:id])
  end
end

in routes.rb file

get '/create_like.js' => 'likes#create_like'

Question: Secondly, my attempts so far have all failed because both the JavaScript file doesn't load and the action doesn't get called aswell.

Anaswer: move app/assets/javascripts/likes/index.js.erb

code to

app/views/likes/create_like.js.erb

you need to pass item_id to

getScript method

$(document).ready(function() {

$('#list > li').dblclick(function(){
  // styling
  $(this).toggleClass('liked');

  // pass ID to controller
  var item_id = $(this).attr("data-id");
  $.getScript("/create_like.js?item_id=" + item_id);
});
});
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top