Rendering partials not working from controller - ruby-on-rails

I've got a home_controller.rb that has different methods whose purpose is to just render render partials that have different content.
I have the urls created in the config
get '/interview', :to => 'home#interview'
get '/chambers', :to => 'home#chambers'
get '/letter', :to => 'home#letter'
get '/drafting', :to => 'home#letter'
and the methods set up that render partials (I was experimenting with symbols vs single quotes) from the home_controller.rb
def chambers
render 'home/chambers'
end
def drafting
render 'drafting'
end
def interview
render :interview
end
However, I'm getting a missing template error (Template is Missing) message when I click the links.
I can get it to work without using partials but rather regular files interview.html.erb (for example) but I would still like to know why it's not working with partials.
Thanks

you need to specify it as partial if you want to render a partial else rails will look for file or an action with that name.
render :partial => 'drafting'
Code for rendering logic in rails https://github.com/rails/rails/blob/5215eed5a3f18c76d70f0f25bca4ff6286c4bac8/actionpack/lib/abstract_controller/rendering.rb#L141

Related

Rails 5.0.0.1 namspaced controller and render partial. bug?

I'm having an issue with render partial: from within a namespaced controller. I should be able to render any partial from the views relative to the views folder, however, I'm unable to do so. It appends the partial path with the namespace, regardless of whatever I do. This controller responds to ajax calls and returns html.
Expected
1) render partial: "foos/bar" => "app/views/foos/_bar.html.haml"
2) render partial: "/foos/bar" => "app/views/foos/_bar.html.haml"
Getting
1) render partial: "foos/bar" => "app/views/ajax_api/foos/_bar.html.haml"
2) render partial: "/foos/bar" => "app/views/ajax_api//foos/_bar.html.haml"
note on 2 extra "/"
It does not matter what I have tried the result is
ActionView::Template::Error:
Missing partial 'insert above output'
Routes
namespace :ajax_api do
resource :setup, only: [] do
post :selection, on: :member
post :deployment, on: :member
end
end
So it appears that namespaces take priority over a defined route, always
However seems an option was added to turn off prefixing of namespace.
see: render partial of another namespace
I think I'm going to refactor my routes, to not use a namespace.
Discussion
A leading slash in the defined route should always take precedence over a namespace?

Routing to static pages in subfolders

Have a Help system for a Rails App, that uses a static page controller.
def show
if valid_page?
render template: "help/#{params[:page]}"
else
render file: "public/404.html", status: :not_found
end
with route
get 'help:page' => 'help#show', :via => [:get]
The Help folder started to become overwhelming with all the static views for the application.
So I wanted to split the views into sub-folders with associated controller - so in the Help folder is now
---Welcome
----index.html.erb
----about.html.erb
----contact.html.erb
---Blog
----index.html.erb
etc
Under the help folder there are two dozen or so sub folders each with 3-6 help files, without creating a route for each subfolder, is there an way to have a single smart route to reference controller(folder) and page.
get 'help:folder:page' => 'help#show', :via => [:get]
def show
if valid_page?
render template: "help/#{params[:folder]}/#{params[:page]}/"
else
render file: "public/404.html", status: :not_found
end
Any ideas?
Here's how it should work:
#config/routes.rb
resources :help, only: [:index, :show] #-> url.com/help/:id
This will allow you to use the following:
#app/controllers/help_controller.rb
class HelpController < ApplicationController
def show
#page = Help.find params[:id]
#no need to rescue this, rails will automatically throw a 404 error if not found
end
end
#app/models/page.rb
class Page < ActiveRecord::Base
#columns id | type | title | body | created_at | updated_at
end
#app/models/help.rb
class Help < Page
end
The main issue you have is that you're storing each page as an .html.erb file. Whilst this will be okay in certain circumstances, in this case it's going to get very messy, very quickly.
You'll be much better creating a Model and table to store the help pages you need, allowing you to collate & invoke them as required. An added benefit to this will be that there will be no validation (Rails will handle it all), and you'll be able to use one view file to get it working:
#app/views/help/show.html.erb
<%= #page.title %>
<%= #page.body %>

Rails - Add action to controller created by scaffold

I'm trying to add an action called rollback to controller.
As I've seen, the only things I should do is writting the new action:
def rollback
puts "ROLLBACK!"
respond_to do |format|
format.html # index.html.erb
format.json { render json: #components }
end
Modify the routes.rb file:
resources :components do
collection do
post :rollback, :as => 'rollback'
end
end
And calling the action from some view:
<%= link_to 'Rollback', rollback_components_path %>
But I get the following error:
Couldn't find Component with id=rollback
app/controllers/components_controller.rb:18:in `show'
That's because instead of going to rollback action, the controller thinks that we are trying to 'show' to component with id 'rollback'.
Something that it seems weird for me is that calling 'new' action rails uses new_component_path (without s, in singular), but if I write rollback_component_path it throws me an error and I cant see the view.
In your routes you require a POST, just clicking a link is by default a GET, so either write
resources :components do
collection do
get :rollback
end
end
and then the link_to will work as expected.
I am assuming the rollback operation is not idempotent, so a POST is semantically better in that case.
If you write your link as follows, then rails will create an inline form for you:
link_to 'Rollback', rollback_components_path, :method => 'post'
Hope this helps.
This will work
routes.rb
resources :components
match "components/rollback" => "components#rollback", :as => :rollback
In views
<%=link_to 'Rollback', rollback_path%>

Ruby on Rails form_remote_tag missing template

I'm using form_remote_tag(:url => {:controller => "home", :action => "search"}, :update => "mydiv"). When I click submit on the form "mydiv" is populated with the error "Template is missing. Missing template home/search.erb in view path app/views". I've tried multiple render options in def search, but they all result in the same error.
It looks like the search method is trying to use it's default render even though I'm specifying what I want.
I've tried:
render 'index'
render :text => 'Return this from my method!'
Is my url incorrect? Is it not submitting back to my home controller's search method?
Try
render :action => 'index'
this will use "index.rhtml" or "index.html.erb".
I will try to explain why it said search.erb is not found, lets take create action for a some model, if there is some error in my create action they it will throw missing template create.html.erb file, since you have some error in your create action rails will try to render the create.html.erb in the page. Hope I explained it clearly.
In an ajax action you can't use redirect_to or render options directly.
try using this in your search action
render :update do |page|
page.replace_html "ur_div_id","partial"
end
The form_remote_tag needs prototype to function. Make sure you are including the :defaults for your javascript libraries namely prototype.
<%= javascript_include_tag :defaults %>

Rails RESTful controller and rendering after custom action

How can I render after executing an action in a restful controller instead of redirecting.
I have a controller with standard actions, and I added a special action that adds data to the resource in question, via a form on the #show page (Think comments on a post). I am validating the input from the form and want to re-render the show action on error and redirect to the show action on success.
I want to render to save the user from inputting their info twice, but when I try to render the show action with an error in the flash[:notice] I get an error saying that I am not specifying an ID. When I do specify an ID, it tries to render a new template that doesn't exist yet.
I am thinking that it should be a as simple as:
def add_comment
if my_validation?
save the object
redirect_to :action => "show", :id => params[:id]
else
render :action => "show", :id => params[:id]
end
end
This is not my actual code, just something I put together just now as an example.
The best way is to re-render the :new
def create
#obj = TheObject.new(params[:object])
render :action => :new unless #obj.save
end
And in the new.html.erb
<% form_for :obj,
:url => object_url(#obj), :html => {:method => :post} do |f| %>
<%= f.text_field :name %>
<% end %>
That way, the inputs in the form will be pre-filled with what the user entered.
Create a new data object and add the values from the form, before you rerender, think it would work then. If you still get problems, try setting a boolean for editing new vs. existing rows, or create two different views entirely.
I've done it before but I don't quite remember how. Sometimes when I used the very typical use of the MVC pattern, it was allmost "automagical", othertimes (as I had to use an old quirky database) I had to code all the magic myself; sometimes usin the .new? function (or what it was called) on the ActiveRecord object, othertimes I used temporary "magic values" for ID (typically alphabetic strings for invalid id values.
(I appologize if I made some mistakes, it's a while since I coded Rails code...)

Resources