Why after render an partial,#users_shown is nil? - ruby-on-rails

In controller, I have #users_shown. In views, I render a partial _attendants.html.haml with #users_shown.
It's okay but there is a button on this page called attend_again, while you click this button, it will render the partial via AJAX with partial _attendants.html.haml.
The question is in the partial _attendants.html.haml, #users_shown is nil. I don't know why.
file _attendants.html.haml like this
- unless #users_shown.blank?
-#users_shown.each do |user|
user.name,user.id

You need to set #users_shown in your controller action that is rendering the ajax _attendants partial. It's a completely separate request, and needs all relevant data set appropriately.

Try add a local to the partial rendering like:
<%= render :partial => "xxxx/_page_attendants", :locals => { :users_shown => #users_shown } %>

Related

How to pass object to partial using controller?

I've been trying to pass my Product object to my rendered partial but no matter what I try it doesn't work. The home page has a quick view button that pops a modal (the partial) and I want to pass the correct product to it.
Route
get 'shop-product-ajax-page', to: "pages#shop_product_ajax_page"
Home Page (shortened to only the link for brevity)
<% #products.each do |product| %>
<%= link_to "Quick View", shop_product_ajax_page_path, :data => {:lightbox => 'ajax'} %>
<% end %>
Controller Action
def shop_product_ajax_page
render :partial => 'pages/shop_product_ajax_page', :layout => false
end
Right now, the button works and displays the HTML in the modal. I want to be able to populate the correct product information for whatever Quick View product is selected.
The problem is that the link is making a completely separate AJAX request, it's hitting the server separately, so the Ruby context you expect (variables etc) isn't available in that new request.
Two choices:
Don't make an AJAX request but render the lightbox as part of the page. You could hide it using display: none or similar, then use Javascript to display it when the link is clicked.
Make the request the way you currently are, but pass in the same parameters that your current controller action is using to get #products and in shop_product_ajax_page do the same thing to hit the database and get the products.
The second choice might be easier without messing with JS. It would be something like:
def shop_product_ajax_page
#products = get_products_from_params(params)
render :partial => 'pages/shop_product_ajax_page', :layout => false
end
private
def get_products_from_params(params)
Product.find(params["product_ids"]) # or whatever you're currently doing
end

Rails partial from different controller in a Bootstrap tab

I have a Home page with 2 Bootstap tabs. I'm having problems with the 2nd tab. I'm trying to render a list of workorders. For that list I'm using dataTables and ajax.
My issue is that workorders/index7.html.erb works fine as a stand alone page. But, I want to use it in a Bootstrap tab on the Home page.
For all my other Bootstrap tab lists, I'm using partials from within the same controller. But, in this case, I need to use a view from the Workorder controller not the Home controller.
This is the code I'm trying in the Home view:
<div class="tab-pane" id="tab2">
<%= render "workorders/index7" %>
</div>
That code gives me:
Missing partial workorders/index7
WHY? If I change the file name to _index7.html.erb the code won't execute to get the json.
But, because it's a partial, starting with _, the connection to the Workorder controller code for index7 doesn't work. I also tried _index7 in the Workorder controller.
The Workorder controller has this code:
def index7
#workorders = Workorder.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: Workorders3Datatable.new(view_context) }
end
end
That code uses a file called workorders3_datatable.rb to get the data via ajax and format it for dataTables.
QUESTIONS:
1) Do I have to use a partial in the Home tab? Or is there a way to render a file called workorders/index7.html.erb in the tab?
2) Why does index7.html.erb use the controller code for index7, yet the partial _index7.html.erb won't use code if I call it _index7 in the controller?
3) I read this "Render will just render the view, it won't run the action associated with it." - is that true?
Thanks for your help - I know this is confusing.
Reddirt
UPDATE 1
The view runs great as workorders/index7 - but, if I change it to a partial and put it in a tab = workorders/_index7 - the controller code for index7 doesn't seem to execute.
1) Do I have to use a partial in the Home tab? Or is there a way to view a file called workorders/index7.html in the tab?
If you want to follow this approach. From Home controller pass the collection (#workorders = Workorder.all)
Then in the home view pass it to the workorders/index7 as locals
<div class="tab-pane" id="tab2">
<%= render "workorders/index7" locals: {workorders: #workorders} %>
</div>
This will make it available to workorders/index7 do remember to change the variable to a local variable workorders.
You need to include :partial in the view for your Home page:
<%= render :partial => "workorders/index7" %>
The app/views/workorders folder will need a file called _index7.html.erb. To accomplish this from your current setup, you can move the contents of index7.html.erb into this partial, and then use:
<%= render :partial => "index7" %>
in the original index7.html.erb. That way you can render that as a whole page and within your Home page as a partial.

Declare a variable in Link so Controller loads separate layout in Rails

I have a link that calls this:
<%=link_to 'Free Trial', '/sign_up', :rel => "#signup", :class => "sign_up_button"%>
Which renders mysite.com/sign_up - This loads a partial in a Jquery light box. However What I would love to do is have a controller statement where if the link above is clicked it renders the page with no layout. But if the user navigates to mysite.com/sign_up from the address bar, they see the same page but with a layout.
I am thinking in my controller something like this:
def sign_up
if :variable == true
render :layout => false
else
render :layout => 'layouts/sign_up'
end
end
then in my link declaring a variable it can pass to the controller? something like
:variable => 'true'
I am thinking about this in the right way? How would the above work?
The main reason for this is so that if mysite.com/login is loaded on its own (without Jquery) then it will still look good!
Thanks
You have two ways :
You can do as you are thinking, and set your partial flag via POST. Replace /signup with /signup?partial=1 and in your controller if params[:partial]
Or you can render conditionnaly looking at request.xhr? (but ajax headers must be setted correctly by your js framework)

Render a view of another controller

What I want to do is have 2 different controllers, client and test_client. The client controller is already built and I want to create a test_client controller that i can use to play around with the UI of the client and adjust it as needed. I am mainly trying to get around the validation i have built into the client and its dependence on an admin controller that loads the data.
so i want the test_client controller to load a sample data set and then render the client controller's index view so i can adjust the clients UI. That is all.
I tried this in the test_clients index method:
class TestClient
def index
render :template => 'client/index'
end
end
but i get an error because it cannot find the client partials as it is looking in the current controllers view for them...
So I have looked into this already and most people say that you should never make such a call but i think that this case is a reasonable usage...I just need to figure out how to get it to work.
You will need to adjust your view so that the path to the partial you need is in the form 'controller/partial'. In this case probably 'client/partial'. Then you can simply use render 'client/index' as before.
So say somewhere in your view you have this:
<%= render :partial => 'info' %>
You will want to change it to this:
<%= render :partial => 'client/info' %>
Convert your client controller views to partials, create empty views for all actions in test_client controller, render client partials for respective test_client views.
Example:
client view
index.html.erb to _index.html.erb
test_client view
index.html.erb
in this view, <%=render :partial => 'clients/index', :locals =>{ }%>
You could do this in a number of ways and everyone is different. One way you could do it, is by putting your finders into a presenter. Then turn some data in the index view into a partial or you can render the template with layout set to false.
Then in the client_test view you can render that index with the presenter associated with it.

how can I cache a partial retrieved through link_to_remote in rails?

I use link_to_remote to pull the dynamic contents of a partial onto the page. It's basically a long row from a database of "todo's" for the day.
So as the person goes through and checks them off, I want to show the updated list with a line through those that are finished.
Currently, I end up needing to click on the link_to_remote again after an item is ticked off, but would like it to redirect back to the "cached" page of to-do's but with the one item lined through.
How do I do that?
Here is the main view:
<% #campaigns.each do |campaign| %>
<!--link_to_remote(name, options = {}, html_options = nil)-->
<tr><td> <%= link_to_remote(campaign.name, :update => "campaign_todo",
:url => {:action => "campaign_todo",
:id => campaign.id
}
) %> </td></tr>
<% end %>
</table>
<div id="campaign_todo">
</div>
I'd like when the New/Create actions are done to go back to the page that redirected it there.
When someone wants to "do" a task, it takes them to the new action. here is the controller:
def create
#contact_call = ContactCall.new(params[:contact_call])
if #contact_call.save
flash[:notice] = "Successfully created contact call."
redirect_to contact_path(#contact_call.contact_id)
else
render :action => 'new'
end
end
I switched to redirect_to :back, which takes me back to the main view shown above...but WITHOUT the PARTIAL. It means I need to reload the partial all over again, which is a time-consuming database call.
1) Is it possible to go back to a view that has a partial called through AJAX and still have those results show up?
2) Can that result, however, be marked via CSS to indicate that it has been "checked off"?
I would render the to-do list item response from javascript ERB files. So when you make the link_to_remote call, instead of redirecting back to the page, instead render javascript.
You'd have the form in /app/views/contact_call/_form.html.erb
/app/views/contact_call/create.js.rjs
page.replace :contact_form, :partial => "contact_call/form", :locals => { :user => #user }
page.visual_effect :highlight, :contact_form
Your controller would then render the javascript, which would in turn replace html on your page with the latest version (and highlight it). And your page would load the partial with strike-through on completed items.
you have to create an ajax call when you mark one item as 'done', in this action you'll need to
update your list item to add the 'line-through' to text-decoration
create a method like 'after_save', to expire your cache
you can read about the CSS 'line-through' here:
http://www.icelab.eu/en/blog/css-4/xhtml-and-css-strike-alternatives-86.htm
and the documentation for expire_page and expire_action is here:
http://api.rubyonrails.org/classes/ActionController/Caching/Sweeping.html
I think you may be able to use action caching on your index action, or whatever the name of the action is that renders your main page.
You can also do page caching and fragment caching, which would work with partials. For more information on Rails caching strategies, see the rails guide:
http://guides.rails.info/caching_with_rails.html

Resources