want to get all db entries by a specific hash and return it as json. I use the following code:
#tasks = Task.find_all_by_hash(params[:hash])
respond_to do |format|
format.json { render :json => #tasks }
end
now i have the problem that my json file isn't correct. it has the following output:
[
{
task: {
hash: "9dfca619f00f5488785f6b74ad1b590beefaee7a88c04884bf197e7679f3"
id: 4
created_at: "2010-12-16T09:09:51Z"
updated_at: "2010-12-16T09:14:10Z"
done: true
name: "Hallo"
}
},
{
task: {
hash: "9dfca619f00f5488785f6b74ad1b590beefaee7a88c04884bf197e7679f3"
id: 5
created_at: "2010-12-16T09:12:37Z"
updated_at: "2010-12-16T09:12:37Z"
done: true
name: "Test"
}
},
...
]
but actually i want it like this:
{ tasks: [
{"id":"1","date_added":"0001-02-22 00:00:00","post_content":"Check out my content, this is loaded via ajax and parsed with JSON","author":"Ryan Coughlin"},
{"id":"2","date_added":"0000-00-00 00:00:00","post_content":"More content, loaded. Lets try to add a form in and post via ajax and append the new data","author":"Billy Bob"}
]}
any advice? thank you!
Try collecting the task alone to an array and create a json object using that. Some thing like
#tasks = Task.find_all_by_hash(params[:hash])
a = []
#tasks.each do |t|
a << t[:task]
end
b = {:tasks => a}
respond_to do |format|
format.json { render :json => b }
end
Related
I'm new to rails,
Please check my code and tell me whats wrong with my use params, because this is how it made sense to me.
Controller:
def create
user = User.find(user_params)
order = user.purchases.new
render json: order.errors if !order.save
basket = params.require(:basket)
basket.each do |b|
i = Item.find(b[:item_id])
render json: i.errors, status: 422 if !i
order.purchases_items.create(item_id: i, quantity: b[:quantity])
end
render nothing: true, status: 201 # location: show action
end
and my test file is sending
test "making order" do
post "/api/users/#{#tuser.id}/orders",
{ basket: [ { item_id: '2', quantity: '5' },
{ item_id: '1', quantity: '4'} ] }.to_json,
{ 'Accept' => Mime::JSON, 'Content-Type' => Mime::JSON.to_s }
assert_response 201
assert_equal Mime::JSON, response.content_type
end
Thanks,
What I basically want to do is store each array element in the array basket from params[:basket], and iterate over it.
Sometime params keys are not get converted into symbols automatically. Can u try passing string "basket" instead of symbol :basket?
I have create a show method in tour controller and want to render the data from the database into json format.
This the definition of the tour controller
class ToursController < ApplicationController
respond_to :json
def show
#tourcategory = Tourcategory.find(params[:id])
#tours= #tourcategory.tours
#tourcategories = Tourcategory.all
render :layout => false
end
end
This is the definition of the show.html.haml view
%h3 Tour for #{#tourcategory.title}
= #tours.to_json
The output of this code is following:
[{"content":"dscfds","created_at":"2015-12-12T09:48:32Z","elementid":"test1","id":8,"jobid":2,"next_button_title":"next","priority":23,"title":"test1","updated_at":"2015-12-12T09:48:32Z"}]
But i just want to render the data in this kind of json format, following:
var tour = {
id: "tour",
steps: [
{
title: "abc",
content: "Click this Button.",
target: "#abc",
placement: "bottom",
showNextButton: false,
skipIfNoElement : true
},
It's not clear what you're trying to achieve but it seems to me that you want to extract certain attributes from your #tours and group them as an array, if that's the case you can do something like this:
(list all the attributes you want inside t.attributes.slice())
tour = { id: "tour", steps: #tours.map { |t| t.attributes.slice("title", "content", "target") } }
and if you want to convert your keys from snake (underscore) to camel format:
tour = {
id: "tour",
steps: #tours.map {|t| t.attributes.slice("title", "content").map {|k,v| [k.camelize(:lower), v]}.to_h}
}
I have the following controller code in a simple Rails API:
class Api::V1::AccountsController < ApplicationController
def index
render json: Account.all
end
def show
begin
render json: Account.includes(:cash_flows).find(params[:id]), include: :cash_flows
rescue ActiveRecord::RecordNotFound => e
head :not_found
end
end
end
The problem with this is that, the generated json have the format:
{
id:2,
name: 'Simple account',
cash_flows: [
{
id: 1,
amount: 34.3,
description: 'simple description'
},
{
id: 2,
amount: 1.12,
description: 'other description'
}
]
}
I need that my generated json is camelCase('cashFlows' instead of 'cash_flows')
Thanks in advance!!!
Following the recommended by #TomHert, I used JBuilder and the available config:
Keys can be auto formatted using key_format!, this can be used to convert keynames from the standard ruby_format to camelCase:
json.key_format! camelize: :lower
json.first_name 'David'
# => { "firstName": "David" }
You can set this globally with the class method key_format (from inside your environment.rb for example):
Jbuilder.key_format camelize: :lower
Thanks!!!
This:
def index
render json: Slide.all.to_json(include: :user)
end
Is rendering this:
[
{
id: 1,
title: 'Hello',
user: {
first_name: 'Guilherme',
last_name: 'Oderdenge',
email: 'guilhermeoderdenge#gmail.com'
}
}
]
Ok. But I just want the first_name from user. There's a way to do this?
Yes, you can do this:
render json: Slide.all.to_json(include: { user: { only: :first_name} )
See the rails api for more information.
Change it like
render json: Slide.all.to_json(:include=>{:user=>{:only=>[:first_name]}})
def update
#product_category = #business_category.product_categories.find(params[:id])
product_category_was = #business_category.product_categories.find(params[:id])
respond_to do |format|
if #product_category.update_attributes(params[:product_category])
share_associations(#product_category, product_category_was) if in_params('_maps_attributes', 'product_category')
format.js
format.html { redirect_to(admin_product_categories_path, :notice => 'Product category was successfully updated.') }
format.xml { head :ok }
else
format.js
format.html { render :action => "edit" }
format.xml { render :xml => #product_category.errors, :status => :unprocessable_entity }
end
end
end
The function share_associations has the parameters #product_category and product_category_was. The problem is, when i call product_category_was.send('images') for example (which i have to call using send since the call is dynamic) it obviously pulls the newest associated images and not the images that were associated. Is there anyway i can get the object to get the images that were associated at the point in time it was made?
I think you need a deep copy of your object, because normal association (=) will only create a reference:
product_category_was = Marshal::load(Marshal::dump(#product_category))
This might not work for all kinds of objects, but for normal Rails objects this should work.
I have no idea what arnep is talking about, nor what problem you're getting. What you're doing works for me on two different finds through an association, and so it should.
irb(main):016:0> s = School.first
=> #<School id: 2, name: "Bar", created_at: "2011-04-09 17:48:57", updated_at: "2011-05-13 09:13:38", confirmed: nil, zipcode: nil>
irb(main):017:0> g1 = s.grades.find 4
=> #<Grade id: 4, name: "4th", type: nil, school_id: 2, created_at: "2011-04-19 03:17:49", updated_at: "2011-05-13 09:15:17">
irb(main):018:0> g2 = s.grades.find 4
=> #<Grade id: 4, name: "4th", type: nil, school_id: 2, created_at: "2011-04-19 03:17:49", updated_at: "2011-05-13 09:15:17">
irb(main):019:0> g1.update_attributes :name => '5th'
=> true
irb(main):020:0> g2
=> #<Grade id: 4, name: "4th", type: nil, school_id: 2, created_at: "2011-04-19 03:17:49", updated_at: "2011-05-13 09:15:17">
irb(main):021:0> g1
=> #<Grade id: 4, name: "5th", type: nil, school_id: 2, created_at: "2011-04-19 03:17:49", updated_at: "2011-05-13 09:16:02">
irb(main):022:0>
In fact, usually people are asking the inverse question - how to get an already instantiated object to reload from the DB. The problem is probably in your share_associations method, or something else you're not showing yet.
I found a way to do something that works for now. It's not the greatest way, but it works for now. I basically created an empty array and pushed the product_categories array into it. This made it so the value was no longer a call so the value does not change. Hopefully this will help someone else eventually.
def update
#product_category = #business_category.product_categories.find(params[:id])
if in_params('_maps_attributes', 'product_category')
media_was = Array.new
media_was = media_was | #business_category.product_categories.find(params[:id]).send(map_type('product_category').pluralize)
end
respond_to do |format|
if #product_category.update_attributes(params[:product_category])
share_associations(#product_category, media_was) if in_params('_maps_attributes', 'product_category')
format.js
format.html { redirect_to(admin_product_categories_path, :notice => 'Product category was successfully updated.') }
format.xml { head :ok }
else
format.js
format.html { render :action => "edit" }
format.xml { render :xml => #product_category.errors, :status => :unprocessable_entity }
end
end
end