Missing template after link_to_remote - javascript

I'm using link_to_remote to update a partial on my page. The problem is that Rails isn't finding my partial.
I am specifying the full path to my partial(an html.erb file) in the controller method:
def my_method
create something
render :partial => '/shared/partials/my_partial_form', :layout => 'false'
end
I know the controller method is getting hit, since "something" gets created. I get the error "Template missing [:controller_name]/[:method_name].js.erb not found".
Can anyone explain why Rails appears to be using a default path to a js.erb?
Thanks in advance!

Rails is responding to the JS format. render :partial doesn't count as the action's 1 render/redirect call per action. Without a proper render or redirect call, Rails will call render with default arguments based on the format, controller and action.
Render :partial just returns text to the caller, it does not build a response. In this case the partial is rendered into HTML, but then nothing is done with it. P.S. :layout => false option is superfluous when rendering a partial.
You want to use render :update or RJS files to do the same through a template.
Assuming you want to replace the entire web page, the short version is do something like this:
def my_method create something
render :update do |page|
page.replace_html :body, :partial => '/shared/partials/my_partial_form'
end
end
Going the RJS route you could create the app/views/resource/my_method.rjs file and fill it with
page.replace_html :body, :partial => '/shared/partials/my_partial_form'

Try removing the / in front of shared.
render :partial => 'shared/partials/my_partial_form', :layout => 'false'

Related

The right way to do remote (ajax) calls in Ruby on Rails

I'm making a Single Page Application with Ruby on Rails (it's my first ruby project ever so I'm definitely missing a lot of stuff yet).
So I have a side menu with some links and the right part of the page is supposed to hold a container which is meant to be filled with some content of partial pages.
The typical menu link I have now looks this way:
<%= link_to t('my-groups'), :controller => 'dashboard', :action => 'mygroups', :remote => true %>
I have a dashboard controller, here's the simplified version of it
class DashboardController < ApplicationController
def mygroups
respond_to do |format|
format.js
end
end
I have a dashboard template with the container div in it
<div class="right_col" role="main">
<h2>This is the default content of center page</h2>
</div>
And here's the routes.rb path for it:
get 'dashboard/mygroups' => 'dashboard#mygroups'
I also have one partial page alogside with my dashboard template and it's called _mygroups.html.erb and a javascript file mygroups.js.erb which is called as my controller action
look at the screenshot of the structure
The contents of this js.erb file are:
$('.right_col').html("<%= escape_javascript(render(:partial => 'mygroups')) %>");
It all works and the partial contents appear inside the container on link click just fine.
But there are still 2 problems I couldn't google the answer for
The questions part:
1) It works with Ajax call but if I simply put this http://localhost:3000/dashboard/mygroups to my browser's navigation line and hit enter, it will give me this error
ActionController::UnknownFormat in DashboardController#mygroups
ActionController::UnknownFormat
Extracted source (around line #70):
def mygroups
respond_to do |format|
format.js end end
How can I avoid this and just redirect to index in this case?
I understand that ajax uses POST, but I tried to use post instead of get in routes.rb for this action, and it didn't work at all
2) What if I have a lot of actions for different partial pages, do I have to create a new js.erb file for each action? Can't it be done in some simplier way with just one file?
3) Is it possible to not specify controller and action on this link explicitly?
<%= link_to t('my-groups'), :controller => 'dashboard', :action => 'mygroups', :remote => true %>
I mean since it's supposed to be a POST ajax request, how come I need to display the url like this http://localhost:3000/dashboard/mygroups to a user?
Add format.html in controller like:
class DashboardController < ApplicationController
def mygroups
if request.xhr?
respond_to do |format|
format.js
end
else
redirect_to root_url
end
end
you can add url in link_to tag like:
<%= link_to t('my-groups'), '/dashboard/mygroups', :remote => true %>
Answers to you questions
When you hit the URL in browser, it sends vanilla HTTP get request(non-ajax) which your controller action is not configured to handle it. You need to add format.html and template named groups.html.erb where generally you will list all the groups, I guess.
respond_to do |format|
format.html
format.js
end
Ideally you have to create separate file for each action but if you can take something common out of different action then you can move common template code to a partial and render it either in a separate template having something special or from the controller action directly.
Yes. The rails way is to use routes helper. Run rake routes to list all available routes in your app and find relevant helpers.
I would strongly suggest to read the rails guide to understand how everything works.

How can I render via CoffeeScript in Ruby on Rails 4

I was trying to solve this problem for a while with no result.
I've wanted to pass variables and load a render into a div using CoffeeScript in rails 4.
(I'm using SpreeCommerce platform).
view:
<%= link_to taxonomy.name,root_path+'t/'+tid, {class: "uno", remote: true} %>
controller:
respond_to do |format|
format.html
format.js # menu.js.coffee.erb
end
menu.js.erb.coffee:
$('div#productos').html("<%= escape_javascript(render :partial => /shared/products) %>")
I'd like to load the page '_products.erb.html' and the partial processes the variables that I give it. As soon as I know, view and controller are ok, the problem is in menu.js.erb.coffee
Any help will be apreciated!
ADDITIONAL:
I've modified the extension to .js.coffee.erb. When I try to run the app, it shows me:
"undefined method `render' for #<#:0xa70317c>"
I tryied using <%= raw escape_javascript( render :partial =>... almost always "render" method give me problems.
NEW INFO:
I added gem 'coffee-script' to the Gemfile (then 'bundle install').
Now, when I click the link_to, it shows me into the HTML <%= escape_javascript(render :partial => /shared/products) %> as a text instead of loading the "partial"... any suggestion please?
I wrote a post about this after struggling through the same problem.
You need to:
Name it menu.js.coffee. Suffixing .erb causes it not to be evaluated as CoffeeScript.
Use raw to escape it.
I used these two on my website. Here's how it looks:
<%= raw render 'path/to/menu.js.coffee' %>
It still processes ERB within your CoffeeScript.
I would recommend changing it from menu.js.erb.coffee to menu.js.coffee.erb.
Rails will process the file extensions from right to left. Meaning right now, your file is treated first as coffeescript, then as ruby, and finally as javascript. It looks like you want to make the ruby substitutions first, then parse the coffeescript into javascript, so that would be menu.js.coffee.erb
First of all, you should change file name from menu.js.erb.coffee to menu.js.coffee.erb and you need configuration file as follow, which is a contribution by cervinka on coffee-rails issue #36
config/initializers/coffee_erb_handler.rb
ActionView::Template.register_template_handler 'coffee.erb', Coffee::Rails::TemplateHandler # without this there will be template not found error
class ActionView::PathResolver < ActionView::Resolver
EXTRACT_METHODS = %w{extract_handler_and_format_and_variant extract_handler_and_format} # name for rails 4.1 resp. 4.0
method_name = EXTRACT_METHODS.detect{|m| method_defined?(m) || private_method_defined?(m)}
raise 'unknown extract method name' if method_name.nil?
old_method_name = "old_#{method_name}"
alias_method old_method_name, method_name
define_method(method_name) do |path, default_formats|
self.send(old_method_name, path.gsub(/\.js\.coffee\.erb$/, '.js.coffee'), default_formats)
end
end

Iterate through array passed from controller

I'm using Ruby on Rails.
Here is my code for the view, where I make a post to the controller, passing parameter "tplangroup.id":
<div id="collapse">
<%= form_tag(tplans_collapse_tplans_path, :method => 'post', :remote => true ) do %>
<%= hidden_field_tag(:tplangroup_id, tplangroup.id) %>
<% end %>
</div>
Here is my code on the controller end, where it parses the necessary data and shoots back array "#ordered_tplans"
def collapse_tplans
#collapsed_tplangroup = Tplangroup.find(params[:tplangroup_id])
tplans_from_tplangroup = #collapsed_tplangroup.tplans
#ordered_tplans = tplans_from_tplangroup.order("favrank DESC")
return #ordered_tplans
end
Since I called :remote => true in the original form located in the view, it passes this array to a file called "collapse_tplans.js"
My question is: what is the best way/practice to parse through this array now passed to the js file, and display its contents in the view? Do I use rails code in the js file to manipulate the object? Or do I do it all in javascript/jquery? What is the best practice, and could you provide any example?
Thanks!
Really kind of depends on how you want to go about it, as with all code, there are many ways to skin a cat. I find the easiest way is to use the return ujs as an erb file (collapse_tplans.js.erb) and from there, choose the element on the page you want to attach the retuned object to, and call a standard erb or haml partial where your iterations can be done clearly.
e.g.
In collapse_tplans.js.erb
$('#my_wacky_element').append("<%= j render(:partial => 'collapse_tplans', :locals => { :ordered_tplans => #ordered_tplans }) %>");
Then in
_collapse_tplans.html.erb
<ul>
<%= ordered_tplans.each do |tplan| %>
<li><%= tplan.attribute %></li>
Here is a RailsCast on how to pass data to js from rails:
http://railscasts.com/episodes/324-passing-data-to-javascript?view=asciicast

How to render a partial from an assets Javascript

I am trying to render a partial from a javascript in my assets directory. I found that I can't call the render method within the assets directory. But I cant move my ajax command out of the assets directory either. So my Question is now, how to pass my ajax result onto the action.js file in my view.
So I call the ajax on a onclick jQuery event:
/app/javascript/mymodel.js.coffee
$(document).ready ->
---some actions ----
$('.myid').click ->
---some action---
$.ajax 'mypath'
dataType: 'json'
success: (result)->
---render result in partial on myid-div---
So how do I pass my beloved result and myid onto:
/app/views/mymodel/show.js.erb
$('.myid').html("<%= escape_javascript( render( :partial => 'myartial') ) %>");
To render it out?
I'm banging my head around this for quite some time, so I would really appreciate some help!
You can call the mymodel controller's method to render your partial, but the file name of partial should start with an underscore _
In your example, these code render :partial => 'show' may work for your to render js if you put them into mymodel controller and you should rename show.js.erb to _show.js.erb in the view of mymodel.
To be optimistic, you should be able to render the _show.js.erb and you can see somethings like render _show.js.erb successful inside your terminal.
But It doesn't means that the rails was processing the js.erb as javascript, because there are syntax error in your js.erb ( I am absolutely sure!! ).
So you may also change
$('.myid').html("<%= escape_javascript( render( :partial => 'myartial') ) %>");
to
$('.myid').html('<%= escape_javascript( render( :partial => 'myartial') ) %>');
Check out my questions for more details. I faced the similar problem before.
It will also show you an example of how to send a ajax call and render .js.erb.
:remote => true will send a ajax request to line_items_path.
And according to the routing, it will call the create method, format.js will render create.js.erb by convention. Alternatively, I can render the js.erb with format.js {render :partial=> "create"} if _create.js.erb exist
$(document).ready ->
---some actions ----
$('.myid').click ->
---some action---
$.ajax 'mypath'
dataType: 'json'
params: (pass in what you need, i don't know the exact syntax, just google it)
success: (result)->
---render result in partial on myid-div---
controller
def show
#result = params[:result]
end
view
show.js.erb
$('#some_id').html('<%= render("mypartial").html_safe %>');
#result is accessible now
Pass your result as a parameter from your AJAX call to your controller method. Then instantiate an instance variable (#result for example from the parameter), that way your views is not able to use the instance variable.

sending variable to a javascript file in RoR

I am using ajax to call a RoR rails function and am new to this.
The function is
def destroy
#fav_company = FavouriteCompany.find(params[:id])
respond_to do |format|
format.js { render :layout=>false }
end
end
In my destroy.js.erb I have
$('#profile_alerts').show();
$('#Fav#{#fav_company.id}').hide();
The first line is working but not the second line. I am suspecting it is unable to access #fav_company.
What should I do? thanks
=====
Some additional information, the call I am making to this function is a link_to with remote => 'true' as such:
<%=link_to "destroy",{:controller=>"favourite_companies",:action=>"destroy", :id=>"#{fav.id}"}, {:remote => true } %>
This:
$('#Fav#{#fav_company.id}').hide();
Should be:
$('#Fav #{#fav_company.id}').hide();
Assuming #fav_company.id presents a variable in the DOM
Since your javascript code is in an ERB file I think you should be using $('#Fav<%=#fav_company.id%>').hide();.
Try to use:
$('#Fav#{escape_javascript({#fav_company.id}).html_safe}').hide();
==================================================================================
Ok, my code, but I does another task:
albums/show.html.haml
= link_to t('write.comment'), new_album_comment_path(#album, :format => :js, :id => #album.id), :remote => true
comments/new.js.haml
$("#comment_form").html("#{escape_javascript(render :partial => "comments/form").html_safe}");
also all code here https://github.com/barthezslavik/mebel - if you found something useful, I'll be happy

Categories

Resources