Rails partial rendering twice on changing the URL - ruby-on-rails

I m new to RoR and i recently figured out that if I change the part of URL from the address bar it is just rendering the partial twice below I m illustrating the same.
So my url is localhost:3000/admin/exp_app/10 so if i refresh this page it gets rendered one time but if i change the url to localhost:3000/admin/exp_app/11 the same request gets twice to controller and it is rendering the partial two times .
Can someone help me?
Below i m attaching the part of code.
exp_controller.rb
def show
authorize! :sales, current_user
#filter = params[:filter] || 'all'
#filter_by = params[:filter_by] || 'all'
#analytics_filter = params[:analytics_filter] || 'all'
#uw = params[:uw_id]
#entity = params[:entity]
#leo_no_brc = params[:leo_no_brc].present?
#exporter_application = User.exp_leads_applications.find(params[:id]) rescue nil
user = User.find(params[:id]) if #exporter_application.nil? || can?(:mexico_sales, current_user)
#total_ltm = #exporter_application.shipment_volume_last_year(nil, false).to_i
#exp_clients = #exporter_application.clients
#exp_applications_clients = #exp_clients.where(status: Client::CLIENT_STATUS_ORDER).group_by(&:status)
#exp_task_instances = #exporter_application.task_instances.where(client_id: nil)
#exporter_application = User.exp_leads_applications.includes(:iec, :contacts,
interactions: [:replies],
task_instances: { interactions: [:replies] },
application: { exporter_user: [:iec] })
end
show.html.erb
<% if params[:_tpl] %>
<div class="admin-section tabpanel row">
<%= render partial: params[:_tpl], locals: { instance: #exporter_application } %>
</div>
<% else %>
<%= render 'admin/header' %>
<%= render partial: 'admin/exporter_applications/show' %>
<%= render 'admin/footer' %>
<% end %>
It is guranteed that this url is not called in partial again admin/exporter_applications/show
Thanks in advance!

Related

simple_form_for: update a part of the content with ajax

I have a form which call a partial:
# form.html.haml
= simple_form_for(resource) do |form|
= form.input :foo
= render partial :some_fields, locals: { form: form }
# _some_fields.html.haml
= form.input :bar
My problem is I have to update the partial with ajax and I don't know how to create the form var from my controller:
def ajax_form_fields
render partial :some_fields, locals: { form: ? }
end
Any idea?
The only way I found to achieve this is to add this line at the beginning of _some_fields.html.haml:
- form ||= nil; simple_form_for(resource) { |f| form ||= f }
So, I don't need to pass the form var to the partial:
def ajax_form_fields
render partial :some_fields
end

How to set cookie so it appears back on form?

I have a field called params[:search_loc] that's for a public user where they can put in there address and get results near there. I'm trying to save it in a cookie so when a public user leaves a page they can come back and have the same address until they change it. Here is the view and the controller. This is what I tried.
Controller
def index
#dad = Dad.find(params[:dad_id])
cookies[:search_loc] = params[:search_loc]
if user_signed_in?
near = Mom.near(#user_location, 500, select: "kids.*")
elsif cookies[:search_loc].present?
near = Mom.near(cookies[:search_loc], 500, select: "kids.*")
elsif params[:search_loc].present?
near = Mom.near(params[:search_loc], 500, select: "kids.*")
end
end
View
<% if params[:search_loc].blank? %>
<%= form_tag dad_kids_path(#dad), method: :get do %>
<%= text_field_tag :search_loc, params[:search_loc] %>
<%= button_tag(type: 'submit') do %>
Save
<% end %>
<% end %>
<% end %>
<% end %>
Right now it doesn't set the cookie for the address but it is saved in the browser. How can I get it to show in the search_loc field after I leave to another page?
You are setting a cookie, but not accessing it. Try this
elsif params[:search_loc].present?
cookies[:search_loc] = params[:search_loc]
near = Mom.near(params[:search_loc], 500, select: "kids.*")
elsif cookies[:search_loc].present?
near = Mom.near(cookies[:search_loc], 500, select: "kids.*")
end

Dynamic Partial Based on Select Box - Rails 2.3.5

I've edited my request to hopefully be clearer. I need to render a partial dynamically based on a previous selection box.
REQUEST belongs to PRODUCT
PRODUCT belongs to CATEGORY
CATEGORY has many PRODUCTS
PRODUCT has many REQUESTS
User hits form: create_request.html.erb
User selects a category, then the products select list is populated (like Railscast 88 - dynamic select boxes)
What I now need is to render different partial forms based on which product is selected. I suck at jquery.
create_request.html.erb:
<%= javascript_include_tag "dynamic_products.js" %>
<% form_for :request, :url => {:controller => :requests, :action => :create_request, :id => params[:id]} do |f| %>
<label>Select Category:</label>
<%= select( "request", "category_id", Category.find( :all).collect { |c| [c.name, c.id] })%></br>
<div id="product_field">
<label>Select Product</label>
<%= select( "request", "product_id", Product.find( :all).collect { |p| [p.name, p.id] })%></br>
</div>
#### and here is where I need help:
#### if request.product_id = 1, render partial _form1
#### if request.product_id = 2, render partial _form2
<button type="submit">Submit</button>
<% end %>
dynamic_products.js.erb:
var products = new Array();
<% for product in #products -%>
products.push(new Array(<%= product.category_id %>, '<%=h product.name %>', <%= product.id %>, <%= product.active %>));
products.sort()
<% end -%>
function categorySelected() {
category_id = $('request_category_id').getValue();
options = $('request_product_id').options;
options.length = 1;
products.each(function(product) {
if (product[0] == category_id && product[3] == 1) {
options[options.length] = new Option(product[1], product[2]);
}
});
if (options.length == 1) {
$('product_field').hide();
} else {
$('product_field').show();
}
}
document.observe('dom:loaded', function() {
categorySelected();
$('request_category_id').observe('change', categorySelected);
});
one reminder first before we start. I'm not sure about this but I think request is a reserved word in rails.
JS
this just observes the dropdown and performs an ajax call
$(document).ready(function() {
$('#request_product_id').change(function() {
$.ajax({ url: '/products/' + this.value + '/form_partial' });
});
});
ROUTES
nothing fancy here either. Just setting up a route where the ajax will go to when it is triggered
resources :products do
get :form_partial, on: :member
end
CONTROLLER
we just fetch the product using :id which is passed from ajax
def form_partial
#product = Product.find params[:id]
end
JS TEMPLATE
you need to create a form_partial.js.erb which will render the partial depending on the product. The code below appends the partial after the product_field div
# app/views/products/form_partial.js.erb
$('#product_partial').remove();
<% if #product.id == 1 %>
$('#product_field').after('<div id="product_partial"><%= escape_javascript render('partial1') %></div>');
<% else %>
$('#product_field').after('<div id="product_partial"><%= escape_javascript render('partial2') %></div>');
<% end %>
UPDATE: for rails 2.x
we just need to change the routes and the js template in order for this to run on rails 2.x
ROUTES 2.x
map.resources :products, member: { form_partial: :get }
JS TEMPLATE 2.x
if I remember correctly, the file should be named form_partial.js.rjs. This will give you a page variable which you can use to add js.
# app/views/products/form_partial.js.rjs
page << "$('#product_partial').remove();"
page << "<% if #product.id == 1 %>"
page << " $('#product_field').after('<div id="product_partial"><%= escape_javascript render('partial1') %></div>');"
page << "<% else %>"
page << " $('#product_field').after('<div id="product_partial"><%= escape_javascript render('partial2') %></div>');"
page << "<% end %>"

Pass variable to a Fancybox in Rails with Content

I have this link in Rails:
<%= link_to "Add to Journal", add_post_journal_path(post), :method => :put %>
However I want transform this link to show a fancybox with the content listing my content to choose. First, I use this code:
<%= link_to "fancy", "#add_post", :class=>"fancybox" %>
but I have errors, because I want pass the actual post to fancybox, so I'm using this code: in add_post.html.erb:
<h1>Escolha o Jornal que deseja adicionar:</h1>
<ul>
<% current_user.journals.each do |journal| %>
<li><%= link_to journal.name,add_post_complete_journal_path(journal),:remote=>true %> </li>
<% end %>
</ul>
and my controller is:
def add_post
#journal_post = JournalsPosts.new
session[:post_add] = params[:id]
end
def add_post_complete
#journal_post = JournalsPosts.create(:post_id => session[:post_add],:journal_id => params[:id])
respond_with #journal_post
end
How can I transform this code to use my content in my fancybox?
Add on your action add_post the next respond with js:
def add_post
#journal_post = JournalsPosts.new
session[:post_add] = params[:id]
respond_to do |format|
format.js
end
end
Add on a file on your views add_post.js.erb with the next content:
$.fancybox('<%= escape_javascript(render(:partial => 'path_to/add_post'))%>',
{
openEffect: "fade",
closeEffect: "fade",
autoSize: true,
minWidth: 480,
scrolling: 'auto',
});
For example, you have add a partial _add_post.html.erb on your views. Now inside this partial you can write your code view:
#code for your view inside partial `add_post.html.erb`
<%= #journal_post %>
<h1>Escolha o Jornal que deseja adicionar:</h1>
<ul>
.
.
Regards!

form_for, fields_for and two models

I have form that create two objects and save them to database.
I want to do next things:
save data in database (booth objects)
validate fields (I have validation in model)
and if validation fail, I want to populate fields with entered data
edit action for this form
Problems:
If I use #report I get:
Called id for nil, which would
mistakenly be 4 error
(can't find object). I have in controller, in encreate action #report = ReportMain.new and in action that render that view.
When I use :report_main (model name) it works, it save data to database, but I can't get fields populated when validation fails.
Questions:
What to do with this two models to make this to work (validation, populating fields, edit)?
Can you give me some advice if approach is wrong?
My view looks like this:
<%= form_for(#report, :url => {:action => 'encreate'}) do |f| %>
<%= render "shared/error_messages", :target => #report %>
<%= f.text_field(:amount) %>
<% fields_for #reporte do |r| %>
<%= r.check_box(:q_pripadnost) %>Pripadnost Q listi
<%= select_tag('nacinpakovanja',options_for_select([['Drveno bure', 'Drveno bure'], ['Kanister', 'Kanister'], ['Sanduk', 'Sanduk'], ['Kese', 'Kese'], ['Posude pod pritiskom', 'Posude pod pritiskom'], ['Kompozitno pakovanje', 'Kompozitno pakovanje'], ['Rasuto', 'Rasuto'], ['Ostalo', 'Ostalo']])) %>
<%= r.text_field(:ispitivanjebroj) %>
<%= r.text_field(:datumispitivanja) %>
<% end %>
<input id="datenow" name="datenow" size="30" type="text" value="<%= #date %>">
<div class="form-buttons">
<%= submit_tag("Unesi izvestaj") %>
</div>
<% end %>
encreate actin in ReportController:
def encreate
#report = ReportMain.new
#reporte = ReportE.new
#reportparam = params[:report_main]
#report.waste_id = params[:waste][:code]
#report.warehouse_id = Warehouse.find_by_user_id(current_user.id).id
#report.user_id = current_user.id
#report.company_id = current_user.company_id
#report.amount = #reportparam[:amount]
#report.isimport = false
#report.isfinished = false
#report.reportnumber = ReportMain.where(:company_id => current_user.company_id, :isimport => false).count.to_i+1
if #report.save
#reporte.report_main_id = #report.id
else
redirect_to(:action => 'exportnew')
return
end
#reporte.vrstaotpada = params[:vrstaotpada]
#reporte.nacinpakovanja = params[:nacinpakovanja]
#reporte.ispitivanjebroj = #reportparam[:ispitivanjebroj]
#reporte.datumispitivanja = #reportparam[:datumispitivanja]
#reporte.q_pripadnost = #reportparam[:q_pripadnost]
#reporte.datumpredaje = #date
if #reporte.save
redirect_to(:action => 'show', :id => #reporte.id)
else
redirect_to(:action => 'exportnew')
end
end
I think your problem in this case is that you use redirect_to instead of render. When you use redirect_to then you lose all the variables from your current action. I would probably do something like this in your encreate action:
if #reporte.save
render :show
else
render :exportnew
end
When you use render then it will use the variables from the current action but the view from the action you send to the render method. So when form_for is called with the #report variable, it is already populated with the values that was sent to encreate. Just make sure that you use the same variable names in the different actions but it looks like you do that already.

Resources