How to render with Fields plugin in Grails - grails

My code:
HotelController:
def search() {
def result = Hotel.list()
render(template: "searchTable", model: [hotelList: result], plugin: "fields")
}
views directory:
templates directory:
Error message:
URI
/hotel/search
Class
org.grails.web.servlet.mvc.exceptions.ControllerExecutionException
Message
null
Caused by
Unable to load template for uri [/hotel/_searchTable]. Template not found.
Around line 24 of grails-app\controllers\com\pool\HotelController.groovy
24: render(template: "searchTable", model: [hotelList: result], plugin: "fields")
Should not be like that because fields plugin searches templates in /templates/_fields directory
If I try to place _searchTable.gsp template in /hotel directory - render method renders it as usual <g:render> tag
compile: org.gerails.plugins:fields is in build.gradle of course

Related

How to change a template location for render_to_string method?

I know render_to_string method searches a template in views folder by default, but can this be changed? I mean, does the template have to be located in the views folder or not? I don't like to have some XML templates in the views.
Now my template is in views/domains/fulfillment/template.xml.erb,
but I would prefer not to have it in views like app/domains/fulfillment/template.xml.erb.
My current code:
def query(params:, file_path:)
ActionController::Base.new.render_to_string(
layout: false,
template: "app/domains/fulfillment/#{file_path}",
locals: params,
).strip
end
I am getting an ActionView::MissingTemplate error now, when the its not in the views folder.
I have tried only to changed the template parameter in render_to_string method and can't find how to change it. Thanks.
You can use the file: option to specify an absolute path to a file instead of using the view paths:
ActionController::Base.new.render_to_string(
layout: false,
file: Rails.root.join("app", "domains", "fulfillment", file_path)
locals: params,
).strip

Rails JBuilder Partial Missing Template Error

I am creating a mountable rails engine for a wrapper around a 3rd party API.
controllers:
app/controllers/myengine/v1/application_controller.rb
app/controllers/myengine/v1/customers_controller.rb
module Myengine
class V1::CustomersController < V1::ApplicationController
respond_to :json
def create
...
end
end
end
models:
app/models/myengine/customer.rb
views:
app/views/myengine/v1/customers/_customer.json.jbuilder
app/views/myengine/v1/customers/create.json.jbuilder
I am using JBuilder for my views. Whenever I hit my create action via a REST client, rails will figure out the appropriate view for it (ie. app/views/myengine/v1/customers/create.json.jbuilder).
However, when I reference the partial inside create.json.jbuilder, it complains that the template is missing.
ActionView::MissingTemplate at /v1/customers
Missing partial myengine/customers/_customer with {:locale=>[:en],
:formats=>[:json], :variants=>[], :handlers=>[:jbuilder]}. Searched in:
engines/myengine/app/views/myengine/v1/customers/create.json.jbuilder, line 1
---------------------------------------------------------------------
ruby
> 1 json.partial! #customer
As you can see its looking for the partial in myengine/customers/_customer when it should be looking in myengine/v1/customers/_customer.
I could add json.partial! 'myengine/v1/customers/customer', customer: #customer to specify where the partial is located and this works. However, typically rails magically knows where to find the partial, just not here for some odd reason.
Your help is much appreciated!!

rails 3.2 with jbuilder swallowing errors, instead rendering missing partial

I'm using Rails 3.2.21 with JBuilder.
I have an example where I'm using an a JBuilder partial inside of a js.erb file to pre populate some fields:
var orderData = <%= raw render :partial => 'orders/orders', formats: [:json], handlers: [:jbuilder], locals: {orders: #orders} %>;
I have a weird problem where if an error is thrown in the jbuilder template, it renders a missing template error. so
If _orders.json.jbuilder looks like this
json.array! orders do |order|
json.someProperty order.a_missing_property
end
I get this:
ActionView::Template::Error (Missing partial orders/orders with {:locale=>[:en], :formats=>[:js, :html], :handlers=>[:erb, :builder, :coffee, :haml, :jbuilder, :riif]}
But if there is no error, this renders properly.
Any idea how my error is getting swallowed?
Update
I've created a demo app here: https://github.com/earnold/error-demo
If you load home/index you get a missing template error. If you comment out the bad line in the template, you render the template normally. What I am trying to do is make sure that errors aren't swallowed, but instead are shown on the page.
I was able to get an answer on Github here: https://github.com/rails/jbuilder/issues/40
Short version: this can be remedied by monkey patching Rails. Put this in an initializer and you're good to go.
if Rails.env.development? || Rails.env.staging?
module ActionView
class Template
protected
def handle_render_error(view, e) #:nodoc:
if e.is_a?(Template::Error)
e.sub_template_of(self)
raise e
else
assigns = view.respond_to?(:assigns) ? view.assigns : {}
template = self
unless template.source
# If an error occurs while the Jbuilder template is being rendered in
# in a nested context, you have a mismatch between the template format
# and the view context. Therefore, this block of code would raise
# a false exception (ActionView::MissingTemplate) and swallow the original
# error. This monkey patch tricks rails into thinking it was a json request
# so that refreshing the source hits the right partial
if template.formats == [:json]
view.lookup_context.formats = [:json]
end
template = refresh(view)
template.encode!
end
raise Template::Error.new(template, assigns, e)
end
end
end
end
end

Ruby on Rails and Ajax

I'm trying to learn ruby on rails and ajax. I've mostly worked through this tutorial: http://ruby.railstutorial.org/
and this: http://edgeguides.rubyonrails.org/working_with_javascript_in_rails.html
Now I'm trying to get the most basic things working so I have a foundation to build on. I would like to dynamically load content after the page loads.
I have a page that gets displayed with the following code in it (app/views/statc_pages/home):
<h1>StaticPages#home</h1>
<p>Find me in app/views/static_pages/home.html.erb</p>
<div name="results" id="results" class="results"></div>
And I have a file in app/assets/javascript/static_pages.js.coffee:
$(document).ready ->
$.ajax(url: "/static_pages/test").done (html) -> $('#results').append html
I have two files in app/views/static_pages/ which are test.js.erb and test.hmtl.erb with the same content. But it doesn't get added to the /home.
My static pages controller only has:
class StaticPagesController < ApplicationController
def home
end
def test
end
end
So far only the home page gets displayed. The coffeescript gets executed but the contents of /test won't get inserted. I'm not sure if the ajax code gets executed.
Edit: config/routes.rb:
AjaxTest::Application.routes.draw do
get "static_pages/home"
get "static_pages/test"
Edit:fixed the following previous edit:
Edit: When I change the ajax url to fetch to "test" i get:
Missing template static_pages/test, application/test with {:locale=>[:en], :formats=>[:js, :html], :handlers=>[:erb, :builder, :coffee]}. Searched in: * "/home/xyious/Programming/AjaxTest/app/views"
Edit: now chrome says that static_pages.js consists of the following:
(function() {
$(document).ready(function() {
return $.ajax({
url: "test"
}).done(function(html) {
return $('#results').append(html);
});
});
}).call(this);
It looks like you are missing the template (view file) for your StaticPages#test action.
Add a file called test.js.erb to your views/static_pages directory.
Are you using firebug javascript console (or chrome dev tools, etc) to debug? does the ajax request to /statis_pages/test execute? and try logging the html variable in the javascript after the request occurs
most likely you need to respond with js format
class StaticPagesController < ApplicationController
def home
end
def test
respond_to do |format|
format.js # should render app/views/static_pages/test.js.erb
end
end
end
checkout the rails casts for full details - http://railscasts.com/episodes/136-jquery-ajax-revised
The default dataType of jQuery's ajax is script. So basically you are send a js request to server asking for some html response.
For such case you need to change ajax to get directly, to send Ajax request as html dataType.
$.get(url: "/static_pages/test").done (html) -> $('#results').append html
Then in controller you need to set not to render layout for ajax request.
def test
if request.xhr?
render 'test', layout: false
return
else
# blah blah
end
end
But, to be frankly this type of requests are okay for experiments but too troublesome in real work.

Rails: render a partial from a plugin

I'm getting a missing template error after I try rendering a partial from a plugin. I have included the files with the following:
%w{ models controllers helpers views }.each do |dir|
path = File.join(File.dirname(__FILE__), 'app', dir)
$LOAD_PATH << path
ActiveSupport::Dependencies.load_paths << path
ActiveSupport::Dependencies.load_once_paths.delete(path)
end
The Models are getting loaded, but as for other things I'm not sure what's going on. The helpers are not getting loaded too because I just copied the contents of the partial from the plugin instead of the render :partial => and then it came up with a helper error.
Question is how to be able to :render :partial => from the views folder in my plugin
For plugin views you usually just copy them to your app/views directory, or the plugin installer copies for you. Views don't work on the $LOAD_PATH the same way models and controllers.
In Rails 2.3.* your vendor/plugins/XXXX/app/views/ directories are automatically included in load paths. So when given the following plugin structure:
vendor/plugins/your_plugin/app/views/shared/_box.html.erb
Yuppie!
You are able to call this partial from, for example, app/views/site/index.html.rb like this:
<%= render 'shared/box' %>

Resources