Build json from ValueObjects in Rails 3? - ruby-on-rails

i was wondering how i can build a json response from a value object?
Situation?
I want to return clear json, only the field i need in the front-end. Which means: All associations should be included in the json. But again: only the fields I need. This i why i would like to use a special value object (defining the field) on top of my models.
Problem?
Is this a good idea? How to build value objects (VOs) with rails?
Thanks for helping

Of course it's possible. Look here:
Here is an example:
konata.to_json(:only => [ :id, :name ])
# => {"id": 1, "name": "Konata Izumi"}
As you're talking about associations:
konata.to_json(:include => :posts)
# => {"id": 1, "name": "Konata Izumi", "age": 16,
"created_at": "2006/08/01", "awesome": true,
"posts": [{"id": 1, "author_id": 1, "title": "Welcome to the weblog"},
{"id": 2, author_id: 1, "title": "So I was thinking"}]}

This one sounds interesting:
http://fabrik42.github.com/acts_as_api/

Related

Rails flexirest model is deconstructing array of 2 objects into an object with 2 properties with an array each

I have this weird error where my flexirest model is being called with
{
"people" => [
{"name" => "Jane", "age" => 33},
{"name" => "John", "age" => 36}
]
}
When the receiving end (node) gets
{
"people": {
"name": ["Jane", "John"],
"age": [33, 36]
}
}
I know it's not the receiving service, because a postman request shows the correct structure. Any idea what might have gone wrong?
Thanks!
Showed this to an experienced senior engineer, he said it was most likely flexirest sending the data as form data.
Added request_body_type :json and now it's sending the correct information.

Matching expressions for Twilio TaskRouter workers on data in objects in arrays

I've got Twilio Taskrouter workers with attributes that look like as follows:
{
"name": "Bob",
"id": "45",
"roles": [
{ "id": "19", "name": "Foobar" },
{ "id": "20", "name": "Foobaz" }
]
}
I'd like to write a queue expression to only match Workers with roles with an id of 20. How would I do that?
It would look something like...
"20" in roles.id
...but this doesn't work. As it seems Taskrouter is not smart enough to "unroll" the ids and match within them (like using a tool like jq). I am not able to find a solution in the Twilio Taskrouter expression docs.
Twilio developer evangelist here.
I can't find a solution for you with the data like that. A workaround I just considered would be to add an array of, for example, role_ids to your worker as well. You can keep the existing array of roles, but add a simpler data type to use in the expression matching.
So, the attributes would look like this:
{
"name": "Bob",
"id": "45",
"roles": [
{ "id": "19", "name": "Foobar" },
{ "id": "20", "name": "Foobaz" }
],
"role_ids": ["19", "20"]
}
And you could then use the expression:
"20" in role_ids

User Grape Entity with Arrays

I was wondering whether Grape Entity would work for rendering arrays of hashes, I thought I remebered it worked but somehow I cannot get it to work right now, am I doing some obvious mistake? Here's my Entity:
class V1::Entities::Searchresult < Grape::Entity
expose :_type, as: :type
expose :_id, as: :id
expose :_score, as: :score
expose :highlight
end
In my API I call the rendering like this:
present result['hits']['hits'], with: V1::Entities::Searchresult, :params => params
The 'result['hits']['hits']' is filled with 10 hashes that contain the data. The data is present. However when I look at the result I get:
[
{
"type": null,
"id": null,
"score": null,
"highlight": null
},
{
"type": null,
"id": null,
"score": null,
"highlight": null
},
......
Am I doing something wrong, or is this simply not possible. I can't seem to dig up any documentation on the array toppic.
Cheers
Tom
I found the error, Grape::Entity::Delegator::HashObject fails to work with hashes that have string keys and not symbols. It cannot extract the values.
data = []
result['hits']['hits'].each do |item|
data << item.symbolize_keys
end
present data, with: V1::Entities::Searchresult, :params => params
This workaround ommits the problem. I will also open a github Issue for a fix since a simple
object[attribute] || object[attribute.to_s]
would solve the whole problem instead of only using
object[attribute]
to read the attribute.

Update an array of object using CouchRest, Rails

Im trying to update a parameter in a collection of objects using Rails, CouchRest.
This is what im doing currently,
class User
property :country
property :some_flag
end
#users = User.by_country(:key => 'country-name')
#users.each do |user|
user.update_attributes({:some_flag => 'true'})
end
Whenever update_attributes failed for a User object i want the entire transaction to be rolled back. How can i achieve this?
Am Using CouchDB. Rails, CouchRest and Not using ActiveRecord.
CouchDB doesn't explicitly support transaction, but there is something called "bulk update" which may be of help:
http://wiki.apache.org/couchdb/HTTP_Bulk_Document_API#Modify_Multiple_Documents_With_a_Single_Request
Example data for the update:
{
"all_or_nothing": true,
"docs": [
{"_id": "0", "_rev": "1-62657917", "integer": 10, "string": "10"},
{"_id": "1", "_rev": "2-1579510027", "integer": 2, "string": "2"},
{"_id": "2", "_rev": "2-3978456339", "integer": 3, "string": "3"}
]
}

Rails 2.3.8: how to parse JSON with field names other than DB columns

I'm sure there's an easy solution for this but I'm new to Rails and need help with syntax.
In my controller I have:
#products = Product.all
format.json { render :json => #products }
And it works fine, returning data with the default column names used in the DB:
"product": {
"created_at": "2010-10-08T17:24:27Z",
"id": 24,
"product_date": "2010-08-08",
"product_name": "Product One",
"updated_at": "2010-10-08T17:36:00Z"
}
What I need is something like:
"product": {
"created_at": "2010-10-08T17:24:27Z",
"id": 24,
"start": "2010-08-08",
"title": "Product One",
"updated_at": "2010-10-08T17:36:00Z"
}
That is, changing product_date to start and product_name to title, but only in the JSON output.
It seems like an easy problem to solve but I'm not sure how to express it in Ruby/Rails syntax, so I would really appreciate any help. I cannot rename the database columns.
If you want to alter the JSON output for all Products, everywhere and all the time, simply override the to_json method on your Product model.
Here's the simple way to do that (in your Product class definition):
def to_json
ActiveSupport::JSON.encode({
:created_at => created_at
:id => id
:start => product_date
:title => product_name
:updated_at => updated_at
})
end
You could get fancier and plug in a custom Serializer, but this should suffice for your purposes. One drawback of doing this so explicitly is that if your schema changes, this will have to be updated. This will also break the options usually available to the to_json method (:include, :only, etc) so, maybe it's not too hot.

Resources