Specifying layout in namespaced controller - ruby-on-rails

I am creating a new version of one of my controllers,
Original Controller:-
class ExampleController < ApplicationController
layout 'filename', only: [:method_name]
...
def method_name
#...some logic...
respond_to do |format|
format.html
format.json {
render json: {}, root: false
}
end
end
...
end
New Controller:-
class V1::ExampleController < ApplicationController
layout 'filename', only: [:method_name]
...
def method_name
#...some logic...
respond_to do |format|
format.html
format.json {
render json: {}, root: false
}
end
end
...
end
I keep getting error:-
Missing template v1/example/filename, application/filename with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :arb, :haml, :jbuilder]}
One of the solution is to create a folder structure v1/example and put my layout file there too. But I do not want to create duplicate copies of this file.
Another is to use a parent controller class of both new and old example_controller and specify layout there(and have a folder structure according to the name of the parent class). But this will be an overkill and also I plan on deleting old controller once all my clients migrate to new versions.
I also tried specifying like this:-
class V1::ExampleController < ApplicationController
layout 'example/filename', only: [:method_name]
...
end
but this also doesn't work.
How to tell my new controller to render layout from the old folder structure.

format.html {
render template: 'path/to/template'
}
Rendering a template
Template rendering works just like action rendering except that it
takes a path relative to the template root. The current layout is
automatically applied.
# Renders the template located in [TEMPLATE_ROOT]/weblog/show.r(html|xml) (in Rails, app/views/weblog/show.erb)
render :template => "weblog/show"`
See reference for #render

Related

respond_to with format.json doesn't find partials

I am overriding devise session controler and while trying to set specific format Rails says there's no partial while it's not true
while I am trying to insert it inside respond_to
class SessionsController < Devise::SessionsController
def new
self.resource = resource_class.new(sign_in_params)
clean_up_passwords(resource)
yield resource if block_given?
respond_to do |format|
format.html
format.json {render(json: { sign_in: render_to_string(partial: 'static_pages/home')})}
end
end
The error is:
Missing partial static_pages/_home with {:locale=>[:en], :formats=>[:json], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :coffee, :jbuilder]}. Searched in: * "D:/project_traveldiary/app/views" * "D:/RailsInstaller/Ruby2.3.3/lib/ruby/gems/2.3.0/gems/devise-4.6.2/app/views"
Looks like it searches for json partial, so try to explicitly specify the format of the partial:
render_to_string(partial: 'static_pages/home', formats: :html)

missing template rails problem with JSON rendering?

Has anyone come across this error before? I've looked online and couldn't find much information, perhaps I didn't render my JSON correctly?
Missing template answer/results, application/results with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :coffee, :jbuilder]}. Searched in: * "/Users/Minhaj/Desktop/my_survey/my_survey/app/views" * "/Users/Minhaj/.rvm/gems/ruby-2.4.1/gems/devise-4.5.0/app/views"
Here is the code. If there is an error, help will be appreciated in fixing it.
def create
#answer = current_survey.answers.create(question_id: question, choice_id: choice)
redirect_to question_survey_path(current_survey)
end
def results
#choices = choices_hash
#results = questions.map do |question|
{
question.question => CountChoicesService.call(question.id)
}
end
respond_to do |format|
format.html { render :nothing => true, :status => 204 }
format.json { render json: #results }
end
end
private
def question
#question ||= params[:question]
end
def choice
#choice ||= params[:choice]
end
def choices
#choices ||= Array.wrap(Choice.all)
end
def choices_hash
choices_hash = {}
choices.each { |choice| choices_hash[choice.id] = choice.choice }
choices_hash
end
def questions
#questions ||= Array.wrap(Question.all)
end
end
I appreciate the help in advance.
Here is how it should look like, controller name is plural
Under your controller directory, you should have this
# app/controller/answers_controller.rb
class AnswersController < ApplicationController
def results
end
end
Now in the views directory,the view namespace should be the same as the controller name.
# app/views/answers/results.html.erb
<h1>Check if this works</h1>
routes.rb
resources :answers do
collection/member do
get :results
end
end
Your problem is that you are not returning. Rails will render the associated template for the action unless you return. Try wrapping your render calls in return().
Side note, why are you using Array.wrap()? ActiveRecord’s all methods are array-like. They wait to execute the query until you actually try to iterate them, and then they act like an array. You shouldn’t need to make them an array. If you ever find that you do, you can call .to_a on them.
One thing to note about the active record record collection though, if you remove anything from its “array”, it will actually do a delete from the database, which may or may not be what you want.

rails 4 template missing error in render in ajax

I have the following ajax function
$.ajax({
url: '/sub_categories/sub_cat',
data: 'sub_cat=45',
success: function() {
alert('success');
}
})
Here is my controller
require 'json'
class SubCategoriesController < ApplicationController
def show
end
def sub_cat
#sub_categories = SubCategory.where(category_id: params[:cat_id])
html = render_to_string 'sub_categories/sub_cat'
response_html true,html
end
end
My application controller
def response_html status,html
respond_to do |format|
format.json {render json: {
status: status,
html: html,
}
}
format.html
end
end
I have json file in sub_categories/sub_cat.json.erb
When I run getting error as
ActionView::MissingTemplate at /sub_categories/sub_cat.json
Missing template sub_categories/show, application/show with {:locale=>[:en], :formats=>[:json], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder, :coffee]}. Searched in:
* "/home/editmehere/Documents/site/name/app/views"
My route.rb has
resources :sub_categories do
get 'sub_cat', on: :collection
end
Why I am getting error like this and how can I solve it. Can anyone help me to solve it.
I'm guessing you're trying to keep your application dry, but why don't you just use this in your SubCategoriesController:
class SubCategoriesController < ApplicationController
def sub_cat
#sub_categories = SubCategory.where(category_id: params[:cat_id])
respond_to do |format|
format.json
format.html
end
end
end
This will allow you to call sub_cat.json.erb without having to pass the status var, or pre-render the HTML. This is just convention, so apologies if it's not what you need. I see a lot of people on here overcomplicate things, when simplicity would work much better
Ajax
Also, I believe you've got a problem with your ajax data var:
data: 'sub_cat=45',
should be
data: {sub_cat: "45"},

missing partials with rails

def some_action
#posts = Post.all
render partial: 'layouts/things'
end
In my layouts directory I have things as partial (_things.html.erb)
My other partials work fine. But it doesn't render partial throwing exception as
Missing partial layouts/things with {:locale=>[:en], :formats=>[:json], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder, :coffee]}. Searched in: * "/my/path/appname/app/views"
Edit-1
def some_action
#posts = Post.all
respond_to do |format|
format.json
end
end
Ok i changed my controller link this but then too same exception.
Edit-2
I have created in my views/controller_name/_some_action.json.erb
This is the controller
def some_action
#posts = Post.all
respond_to do |format|
format.json { render json: #posts }
end
end
My _some_action.json.erb file has
<%= render partial: 'shared/information', post: #posts.name %>
And created _information..js.erb in views shared directory
MY _information.js.erb has sample text as
test
I am getting json response from controller i checked with inspect element. But it is not render actual text i need (i.e., test)
well, IMHO you need to name your partial like
_things.js.erb
or no?
As Jacub Kuchar mentions, if you're trying to provide a JSON response, your partial should be named accordingly (i.e. _things.js.erb). You should also put it in the 'shared' directory rather than 'layouts' as it's a partial, not a layout.
However, I'd also keep the logic of which view to render of the controller and let the view itself handle it.
So your controller can simply say:
respond_to :json # (and whatever other response types you want to support: xml, etc)
def some_action
respond_with #posts = Post.all
end
And then having a matching view, under views/{controller name}/some_action.js.erb, which says:
<%= render partial: 'shared/things', posts: #posts %>
That way your controller isn't polluted with view logic.

"Template is missing" when rendering Liquid template

I'm trying to render a liquid template that is stored in the database.
Here is my 'show' action in the controller:
def show
#organization = Organization.find_by_subdomain(request.subdomain)
#template = Liquid::Template.parse(Template.find(#organization.current_template).body)
#page = #organization.pages.find(params[:id])
respond_to do |format|
format.html { render #template.render('page' => #page), :template => false}
format.json { render json: #page }
end
end
However, when I visit the page, I get a "Template is Missing" exception with the following error (note that "testing testing" is the body attribute of the page object, which is currently the only thing being rendered in the template):
Missing template /testing testing with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :coffee, :haml]}.
Searched in: * "/Users/ashercohen/Documents/Rails/Vocalem-Rails/app/views"
* "/Users/ashercohen/.rvm/gems/ruby-1.9.3-p194/gems/twitter-bootstrap-rails-2.1.1/app/views"
* "/Users/ashercohen/.rvm/gems/ruby-1.9.3-p194/gems/devise-2.1.2/app/views"
Why is it trying to find another template, when I've specifically pass the :template => false argument? Is there something I'm missing here? I'm trying to bypass using any template files, as it seems like they shouldn't be needed here (though am not strongly opposed if I am wrong).
Because render almost always takes a filename, while #template.render('page' => #page) contains the plain html. You should invoke render like this:
render :text => #template.render('page' => #page), :content_type => :html

Resources