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
Related
I have a mongoid criteria categories and I need to convert to an array. I'm using categories.to_a but this dont works and always that the mongoid criteria is iterate by .map it's doing a .find a new query.
How can I fix this?
def self.mapOffers (array, user)
array.map { |u|
{
:id => u.id.to_s,
:name => u.name,
:description => u.description,
:price => u.price,
:url => u.url,
:categories => Category.mapCategories(u.categories.to_a, user),
:picture => u.picture.url,
:accepts_cash => u.accepts_cash_transactions,
:location => {
:longitude => u.longitude,
:latitude => u.latitude,
:street => u.street,
:neighborhood => u.neighborhood,
:number => u.number,
:zip => u.zip,
:city => u.city,
:state => u.state,
:complement => u.complement,
:country => u.country,
},
:fixedMeetingPoint => u.fixedMeetingPoint,
:meetingPoint => {
:street => u.meetingPointStreet,
:neighborhood => u.meetingPointNeighborhood,
:number => u.meetingPointNumber,
:zip => u.meetingPointZip,
:city => u.meetingPointCity,
:state => u.meetingPointState,
:complement => u.meetingPointComplement,
:country => u.meetingPointCountry,
:latitude => u.meetingPointLatitude,
:longitude => u.meetingPointLongitude,
},
:notes => u.notes,
}}
end
def self.mapCategories (array, user)
array.map { |u| {
:id => u.id.to_s,
:name => u.name,
:selected => !user.nil? && u.users.include?(user),
:picture => u.picture.url,
}}
end
Starting from criteria:
scope = Band.where(name: 'foo')
... retrieve the complete result set from the database and store in an array:
bands = scope.to_a
... then iterate the array any number of times:
bands.each { |band| ... }
bands.each { |band| ... }
I've integrated Shippo with my Ruby on Rails Spree platform. Everything seems to be working great, except that when I go to create a transaction to print shipping labels, I get an error in the response.
Here's my response:
#<Transaction:0x3feee363470c[id=1b419434531e4b43b438c54b93e2a9f5]
{"object_state"=>"VALID", "status"=>"ERROR", "object_created"=>"2017-06-27T23:11:54.567Z", "object_updated"=>"2017-06-27T23:11:55.330Z", "object_id"=>"xxxx", "object_owner"=>"----#gmail.com", "test"=>true, "rate"=>{"object_id"=>"xxxx", "amount"=>"6.52", "currency"=>"USD", "amount_local"=>"6.52", "currency_local"=>"USD", "provider"=>"USPS", "servicelevel_name"=>"Priority Mail", "servicelevel_token"=>"usps_priority", "carrier_account"=>"xxxx"}, "tracking_number"=>"", "tracking_status"=>nil, "tracking_history"=>[], "tracking_url_provider"=>"", "label_url"=>"", "commercial_invoice_url"=>nil, "messages"=>[#<Hashie::Mash code="" source="USPS" text="Request failed. Please try again or contact Shippo support at support#goshippo.com.">], "order"=>nil, "metadata"=>"", "parcel"=>"xxxx"}->#<Shippo::API::ApiObject created=2017-06-27 23:11:54 UTC id="1b419434531e4b43b438c54b93e2a9f5" owner="xxxx#xxxx.com" state=#<Shippo::API::Category::State:0x007fddbca5a2e8 #name=:state, #value=:valid> updated=2017-06-27 23:11:55 UTC>
Here's the code used to create the label:
def self.createLabel(order_info)
shipping_info = order_info.shipping_address
stock_location = order_info.store.stock_location
address_from = {
:name => stock_location.name,
:company => order_info.store.name,
:street1 => stock_location.address1,
:street2 => stock_location.address2,
:city => stock_location.city,
:state => "#{Spree::State.find(stock_location.state_id)}",
:zip => stock_location.zipcode,
:country => "#{Spree::Country.find(stock_location.country_id)}",
:phone => stock_location.phone,
}
address_to = {
:name => "#{shipping_info.firstname} #{shipping_info.lastname}",
:company => shipping_info.company,
:street1 => shipping_info.address1,
:street2 => shipping_info.address2,
:city => shipping_info.city,
:state => "#{Spree::State.find(shipping_info.state_id)}",
:zip => shipping_info.zipcode,
:country => "#{Spree::Country.find(shipping_info.country_id)}",
:phone => shipping_info.phone,
:email => order_info.email
}
parcel = {
:length => getLength(order_info),
:width => getWidth(order_info),
:height => getHeight(order_info),
:distance_unit => :m,
:weight => getWeight(order_info),
:mass_unit => :lb
}
shipment = {
:address_from => address_from,
:address_to => address_to,
:parcels => parcel
}
#Shippo Carrier ids
#ups = Rails.application.secrets.ups_shippo_id
#usps = Rails.application.secrets.usps_shippo_id
transaction = Shippo::Transaction.create(
:shipment => shipment,
:carrier_account => "#{#usps}",
:servicelevel_token => "usps_priority",
:label_file_type => "PDF",
:async => false
)
end
Has anyone run into this issue before? I've looked at their documentation and cannot find any reason for a "status"=>"ERROR" message, when the "object_state"=>"VALID".
I'm happy to post more code if needed. Thanks.
What I found with lots of trial and error, was that the products I was sending to Shippo actually exceeded the weight the shipping carrier would allow in a package. (This was because my database was a bunch of dummy data). Be sure to be setting your measurement units as well, here:
parcel = {
:length => getLength(order_info),
:width => getWidth(order_info),
:height => getHeight(order_info),
:distance_unit => :m,
:weight => getWeight(order_info),
:mass_unit => :lb
}
After changing the data in my database to have reasonable weights on the products, this error went away.
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] } })
I currently have this:
data = []
products.each do |product|
categories = product.shop_categories.select("shop_categories.id, shop_categories.name").map do |category|
{
:name => category.name,
:category_id => category.id.to_s
}
end
data << {
:name => product.name,
:product_id => product.productid,
:manufacturer => product.manufacturer,
:detail => product.description,
:categories => categories,
:sales_rank => product.sales_rank,
:sale_price => product.sale_price.to_f,
:price => product.price.to_f,
:images => product.images,
:url => product.url,
:is_rated => current_user.voted_for?(product),
:is_liked => current_user.voted_as_when_voted(product),
:is_in_wishlist => current_user.has_product_in_wishlist?(product)
}
end
This part where products are searched for its shop_categories are taking up a huge amount of time to query since every product (100 per run) when it searches for the products' shop_categories.
Is there a way to minimize the number of queries or at least minimize the CPU being used up by this process?
Use includes to eager-load the association:
data = Product.includes(:shop_categories).collect do |product|
{
:name => product.name,
:product_id => product.productid,
:manufacturer => product.manufacturer,
:detail => product.description,
:categories => product.categories.collect { |c| { :name => c.name, :category_id => c.id.to_s } },
:sales_rank => product.sales_rank,
:sale_price => product.sale_price.to_f,
:price => product.price.to_f,
:images => product.images,
:url => product.url,
:is_rated => current_user.voted_for?(product),
:is_liked => current_user.voted_as_when_voted(product),
:is_in_wishlist => current_user.has_product_in_wishlist?(product)
}
end
I'm using this code to convert a model to json. If i try to use an include 2nd level like this:
p = Product.includes({ :variants => { :stocks => :size } }).where(:id => params[:id]).first
render :json => p.variants.to_json(:include => { :stocks => { :include => :size } })
I receive this error:
undefined method `macro' for nil:NilClass
How I can solve that?
Try this:
render :json => p.variants.map { |v| v.as_json(:include => {:stocks => {:include => :size}}) }
Info about Object#as_json/to_json here.