Ruby 'if' condition in rjs - ruby-on-rails

I want to insert a user in the userlist only if the user object (#row) is not nil. How do I do the insert conditionally in an rjs template?
page.insert_html :bottom, :userlist,
render(:partial => "user", :locals =>
{ :user => #row, :myid => #row.id })
thanks much.

exactly how you would do it in regular ruby
if #row
page.insert_html(:bottom, :userlist, render(:partial => "user", :locals => { :user => #row, :myid => #row.id }))
end
or if you want it on one line
page.insert_html(:bottom, :userlist, render(:partial => "user", :locals => { :user => #row, :myid => #row.id })) if #row

page.insert_html :bottom, :userlist, render(:partial => "user", :locals => { :user => #row, :myid => #row.id }) unless #row.blank?

Related

showing error "uninitialized constant Spree::ProductTaxon" while updating spree_products_taxons table in spree

I want to update spree_products_taxons table, but it is showing the error above. What am I am doing wrong?
def import_update
require 'csv'
file = params[:file]
CSV.foreach(file.path, headers: true) do |row|
#prod = Spree::Product.find(row["id"])
#var = Spree::Variant.find_by(product_id: #prod.id)
Spree::Product.where(:id => row["id"]).update_all(:name => row["name"], :meta_description => row["meta_description"], :shipping_category_id => row["shipping_category_id"], :description => row["description"], :meta_keywords => row["meta_keywords"], :tax_category_id => row["tax_category_id"], :available_on => row["available_on"], :deleted_at => row["deleted_at"], :promotionable => row["promotionable"], :meta_title => row["meta_title"], :featured => row["featured"], :supplier_id => row["supplier_id"])
Spree::Variant.find_by(id: #var.id).update(:cost_price => row["cost_price"], :depth => row["depth"], :height => row["height"], :width => row["width"], :weight => row["weight"], :tax_category_id => row["tax_category_id"], :is_master => row["is_master"], :position => row["position"], :cost_currency => row["cost_currency"], :deleted_at => row["deleted_at"], :track_inventory => row["track_inventory"], :tax_category_id => row["tax_category_id"])
Spree::Price.find_by(variant_id: #var.id).update(:amount => row["master_price"], :currency => row["cost_currency"], :deleted_at => row["deleted_at"])
Spree::ProductTaxon.find_by(product_id: #prod.id).update(:taxon_id => row["taxon_id"])
#prop = Spree::ProductProperty.find_by(product_id: #prod.id)
Spree::Property.find_by(id: #prop.property_id).update(:name => row["name"], :presentation => row["presentation"])
Spree::ProductProperty.find_by(product_id: #prod.id).update(value => row["value"])
stock_loc = Spree::StockLocation.find_by(supplier_id: #prod.supplier_id)
Spree::StockItem.where(:variant_id => #variants.id, :stock_location_id => stock_loc.id).update_all(:count_on_hand => row["count_on_hand"], :backorderable => row["backorderable"])
end
redirect_to admin_products_path, notice: "Products Updated."
end
Although the table is called spree_products_taxons (see schema.rb) for some reason the model is Spree::Classification.
You table is spree_products_taxons so it's expecting Spree::ProductsTaxon (mind that its Products NOT Product) model class. Make sure your model should be named as Spree::ProductsTaxon
I can see you are using Spree::ProductTaxon in your code. Please update and try.
Hope it helps.

possible to nest method calls on to_json

I'm trying to do something like this:
render :json => r.to_json(:methods => [:food_item => {:method => :price_value}])
but it's not working. Is something like this even possible?
thx
edit 1
no association
def food_item
MenuItem.find(food_id)
end
Is food_item an ActiveRecord association? If so, you could try
render :json => r.to_json(:include => { :food_item => { :only => :price_value } })
I'll refine my answer in response to "edit 1". First, remove your food_item method and add an actual association like this:
belongs_to :food_item, :class_name => "MenuItem", :foreign_key => "food_id"
and then do
render :json => r.to_json(:include => { :food_item => { :only => [:price_value] } })

Rails 3.1 deep nesting with RABL

I'm using the RABL gem to render JSON user data for users of comments which are children of annotations which are children of images. I'd like to do something similar to:
object #image
node :annotations do
#image.annotations.map { |a| {
:id => a.id,
:x1 => a.x1,
:x2 => a.x2,
:y1 => a.y1,
:y2 => a.y2,
node :comments do
#image.annotations.comments.map { |c| {
:body => c.body,
:user_id => c.user_id,
:name => User.find(c.user_id).name,
:user_icon => user_icon(User.find(c.user_id), 'square', 30)
}}
end
}}
end
I know this isn't valid in RABL, I also tried using child instead of node, but couldn't access the user data that way. How should I go about doing this and whats the proper syntax to make this happen?
I got this answer from #calvin-l. The trick was to just map the a.comments then grab the data from each comment that way:
node :annotations do
#image.annotations.map { |a| {
:id => a.id,
:x1 => a.x1,
:x2 => a.x2,
:y1 => a.y1,
:y2 => a.y2,
:comments => a.comments.map { |c| {
:body => c.body,
:created_at => c.created_at,
:user => {
:id => c.user.id,
:facebook_id => c.user.facebook_id,
:name => c.user.name,
:username => c.user.username
}
}}
}}
end

AJAX update of accepts_nested_attributes_for partials

My current working environment is Rails 2.3.8 (various reasons why my company hasn't moved to Rails 3).
I'm trying to update elements of a multi-model form via AJAX calls - the idea being to replace certain dropdowns depending on how the user selects or fills in other fields.
I have previously managed to get this working by using non-form based partials - the problem I have now is to reproduce the AJAX updating of the select dropdowns when the partials are based around form_for and fields_for.
Sorry for the following wall of text - i've tried to cut it down as much as possible (the code itself does work on my test site).
How do I generate the form builder elements in the Outbreak controller and then pass this to the category partial to take the place of incident_form?
Any pointers would be great :D
Models
class Outbreak < ActiveRecord::Base
has_many :incidents, :dependent => :destroy
has_many :locations, :through => :incidents
accepts_nested_attributes_for :locations, :allow_destroy => true, :reject_if => :all_blank
accepts_nested_attributes_for :incidents, :allow_destroy => true, :reject_if => :all_blank
end
class Incident < ActiveRecord::Base
belongs_to :outbreak
belongs_to :location
belongs_to :category
belongs_to :subcategory
belongs_to :subtype
end
class Location < ActiveRecord::Base
has_many :incidents, :dependent => :destroy
has_many :outbreaks, :thorugh => incidents
end
Views
_form
<% form_for(#outbreak, :html => {:multipart => true}) do |form| %>
<%= render :partial => 'outbreak_type_select', :locals => {:outbreak_types => #outbreak_types, :f => form } %>
<% form.fields_for :incidents do |incident_form| %>
<%= render :partial => 'category_select', :locals => {:categories => #categories, :incident_form => incident_form} %>
<%= render :partial => 'subcategory_select', :locals => { :subcategories => #subcategories, :incident_form => incident_form } %>
<% end %>
<% end %>
_outbreak_type_select
<% with_str = "'outbreak_type=' + value " %>
<% if #outbreak.id %>
<% with_str << "+ '&id=' + #{outbreak.id}" %>
<% end %>
<%= f.collection_select(:outbreak_type, #outbreak_types, :property_value, :property_value, {}, {:onchange => "#{remote_function(:url => { :action => "update_select_menus"}, :with => with_str)}"} ) %>
_category_select
After calling update_select_menus how to generate the incident_form
<%= incident_form.collection_select( :category_id, #categories, :id, :name, {:prompt => "Select a category"}, {:onchange => "#{remote_function(:url => { :action => "update_subcategory"}, :with => "'category_id='+value")}"}) %>
RJS
begin
page.replace_html 'outbreak_transmission_div', :partial => 'outbreaks/transmission_mode_select', :locals => {:transmission_modes => #transmission_modes }
rescue
page.insert_html :bottom, 'ajax_error', '<p>Error :: transmission modes update select</p>'
page.show 'ajax_error'
end
begin
page.replace_html 'incident_category_select', :partial => 'outbreaks/category_select', :locals => { :categories => #categories }
rescue
page.insert_html :bottom, 'ajax_error', '<p>Error :: incident category update select</p>'
page.show 'ajax_error'
end
Controllers
Outbreak
def new
#outbreak = Outbreak.new
#outbreak.incidents.build
#outbreak.locations.build
#just the contents for the dropdowns
#categories = Category.find(:all, :conditions => {:outbreak_type => "FOODBORNE"}, :order => "outbreak_type ASC")
#subcategories = Subcategory.find(:all, :order => "category_id ASC")
end
def update_select_menus
#outbreak_type = params[:outbreak_type].strip
if params[:id]
#outbreak = Outbreak.find(params[:id])
else
#outbreak = Outbreak.new
#outbreak.incidents.build
#outbreak.locations.build
end
if #outbreak_type == "FOODBORNE"
ob_type_query = "OUTBREAKS:TRANSMISSION_MODE:" << #outbreak_type
#transmission_modes = Property.find(:all, :conditions => {:field => ob_type_query})
ob_type_query = "INVESTIGATIONS:CATEGORY:" << #outbreak_type
#sample_types = Property.find(:all, :conditions => {:field => ob_type_query})
#categories = Category.find(:all, :conditions => { :outbreak_type => "FOODBORNE"})
#subcategories = Subcategory.find(:all, :conditions => { :category_id => #categories.first.id})
#subtypes = Subtype.find(:all, :conditions => { :subcategory_id => #subcategories.first.id})
elsif #outbreak_type == "NON-FOODBORNE"
ob_type_query = "OUTBREAKS:TRANSMISSION_MODE:" << #outbreak_type
#transmission_modes = Property.find(:all, :conditions => {:field => ob_type_query})
ob_type_query = "INVESTIGATIONS:CATEGORY:" << #outbreak_type
#sample_types = Property.find(:all, :conditions => {:field => ob_type_query})
#categories = Category.find(:all, :conditions => { :outbreak_type => "NON-FOODBORNE"})
#subcategories = Subcategory.find(:all, :conditions => { :category_id => #categories.first.id})
#subtypes = Subtype.find(:all, :conditions => { :subcategory_id => #subcategories.first.id})
end
respond_to do |format|
format.html
format.js
end
end
Found a work around based on http://www.treibstofff.de/2009/07/12/ruby-on-rails-23-nested-attributes-with-ajax-support/
This should probably go in Outbreak helper (in Outbreak controller atm)
def update_select_menus
#outbreak_type = params[:outbreak_type].strip
#next_child_index will only be used if
#next_child_index ? params[:next_child_index] : 0
if params[:id]
#outbreak = Outbreak.find(params[:id])
else
#outbreak = Outbreak.new
#outbreak.risks.build
#outbreak.incidents.build
#outbreak.locations.build
end
if #outbreak_type == "FOODBORNE"
ob_type_query = "OUTBREAKS:TRANSMISSION_MODE:" << #outbreak_type
#transmission_modes = Property.find(:all, :conditions => {:field => ob_type_query})
ob_type_query = "INVESTIGATIONS:CATEGORY:" << #outbreak_type
#sample_types = Property.find(:all, :conditions => {:field => ob_type_query})
#categories = Category.find(:all, :conditions => { :outbreak_type => "FOODBORNE"})
#subcategories = Subcategory.find(:all, :conditions => { :category_id => #categories.first.id})
#subtypes = Subtype.find(:all, :conditions => { :subcategory_id => #subcategories.first.id})
elsif #outbreak_type == "NON-FOODBORNE"
ob_type_query = "OUTBREAKS:TRANSMISSION_MODE:" << #outbreak_type
#transmission_modes = Property.find(:all, :conditions => {:field => ob_type_query})
ob_type_query = "INVESTIGATIONS:CATEGORY:" << #outbreak_type
#sample_types = Property.find(:all, :conditions => {:field => ob_type_query})
#categories = Category.find(:all, :conditions => { :outbreak_type => "NON-FOODBORNE"})
#subcategories = Subcategory.find(:all, :conditions => { :category_id => #categories.first.id})
#subtypes = Subtype.find(:all, :conditions => { :subcategory_id => #subcategories.first.id})
end
#pathogen_types = Property.find(:all, :conditions => {:field => "PATHOGENS:CATEGORY"})
#outbreak_types = Property.find(:all, :conditions => {:field => "OUTBREAKS:OUTBREAK_TYPE"} )
render :update do |page|
page.replace 'outbreak_transmission_div', :partial => 'transmission_mode_select_update'
page.replace 'incident_category_select', :partial => 'incident_category_select_update'
page.replace 'incident_subcategory_select', :partial => 'incident_subcategory_select_update'
page.replace 'incident_subtype_select', :partial => 'incident_subtype_select_update'
end
end
In the Outbreak view (although since this partial is related to Incident it should probably go in that view instead)
<% ActionView::Helpers::FormBuilder.new(:outbreak, #outbreak, #template, {}, proc{}).fields_for :incidents,{:child_index => #next_child_index} do |this_form| %>
<div id="incident_category_select">
<%= render :partial => 'category_select', :locals => {:incident_form => this_form } %>
</div>
<% end %>
The ActionView::Helpers::FormBuilder is used to produce the required fields_for form - The website article goes through this in more detail.
The resulting index is set by the #next_child_index variable which can be passed to the controller by the original AJAX call (for example #next_child_index = 1, then the resulting form element name will be outbreak [incidents_attributes] [1] [category_id] ) - I haven't used this in this example because although in future I want the form to support more than one location per Outbreak for this initial run-through it will just accept a single Location - Incident per Outbreak.
_category_select.erb partial (in Outbreak view atm)
<% with_str = "'category_id=' + value " %>
<% if #outbreak.id %>
<% with_str << "+ '&id=' + #{#outbreak.id}" %>
<% end %>
<%= incident_form.collection_select( :category_id, #categories, :id, :name, {:prompt => "Select a category"}, {:onchange => "#{remote_function(:url => { :action => "update_subcategory"}, :with => with_str)}"}) %>
The with_str is just to optionally pass the Outbreak id if it exists to the controller to find the Outbreak record to produce the form and if not to build a new Outbreak and associated nested attributes like Incidents and Locations.
The must be neater ways of doing this - especially the FormHelper and passing the Outbreak id via the optional with string.

link_to_remote not updating div

I'm using link_to_remote to update a div asynchronously, but it does not work. I have to refresh the page in order to see the change.
I use this to generate the links.
http://ruby.pastebin.com/m1d83be81
"padding-left:30px", :display => "table-row" ) do %>
{ :success => 'entry_' + entry.id.to_s},
:url =>{ :controller => :entries, :action => :increment ,:id => entry.id},
:with => "'amount=' +prompt('Amount')")%>
{ :success => 'entry_' + entry.id.to_s},
:url =>{ :controller => :entries, :action => :decrement ,:id => entry.id},
:with => "'amount=' +prompt('Amount')")%>
{ :success => 'entry_' + entry.id.to_s},
:url =>{ :controller => :entries, :action => :update ,:id => entry.id},
:with => "'amount=' +prompt('Amount')")%>
The corresponding actions all look like this:
def increment
#entry = Entry.find(params[:id])
#entry.amount += params[:amount].to_i
#entry.save!
render :partial=>"entry", :object=>#entry
end
Remove the :success tag in your update clause and test:
:update => 'entry_' + entry.id.to_s
I have found it helpful to specify the div to be updated in an :update in the controller action.

Resources