nesquena / rabl Goto Github PK
View Code? Open in Web Editor NEWGeneral ruby templating with json, bson, xml, plist and msgpack support
Home Page: http://blog.codepath.com/2011/06/27/building-a-platform-api-on-rails/
License: MIT License
General ruby templating with json, bson, xml, plist and msgpack support
Home Page: http://blog.codepath.com/2011/06/27/building-a-platform-api-on-rails/
License: MIT License
After update rabl gem version from 0.2.8 to 0.3.0 have the Error Message when i try to print date
The stack trace
gems/multi_json-1.0.3/lib/multi_json/vendor/ok_json.rb:416:in `valenc'
gems/multi_json-1.0.3/lib/multi_json/vendor/ok_json.rb:422:in `objenc'
gems/multi_json-1.0.3/lib/multi_json/vendor/ok_json.rb:422:in `each'
gems/multi_json-1.0.3/lib/multi_json/vendor/ok_json.rb:422:in `map'
gems/multi_json-1.0.3/lib/multi_json/vendor/ok_json.rb:422:in `objenc'
gems/multi_json-1.0.3/lib/multi_json/vendor/ok_json.rb:408:in `valenc'
gems/multi_json-1.0.3/lib/multi_json/vendor/ok_json.rb:422:in `objenc'
gems/multi_json-1.0.3/lib/multi_json/vendor/ok_json.rb:422:in `each'
gems/multi_json-1.0.3/lib/multi_json/vendor/ok_json.rb:422:in `map'
gems/multi_json-1.0.3/lib/multi_json/vendor/ok_json.rb:422:in `objenc'
gems/multi_json-1.0.3/lib/multi_json/vendor/ok_json.rb:408:in `valenc'
gems/multi_json-1.0.3/lib/multi_json/vendor/ok_json.rb:427:in `arrenc'
gems/multi_json-1.0.3/lib/multi_json/vendor/ok_json.rb:427:in `map'
gems/multi_json-1.0.3/lib/multi_json/vendor/ok_json.rb:427:in `arrenc'
gems/multi_json-1.0.3/lib/multi_json/vendor/ok_json.rb:409:in `valenc'
gems/multi_json-1.0.3/lib/multi_json/engines/ok_json.rb:15:in `encode'
gems/multi_json-1.0.3/lib/multi_json.rb:72:in `encode'
rabl (0.3.0) lib/rabl/engine.rb:50:in `to_json'
rabl (0.3.0) lib/rabl/engine.rb:28:in `send'
rabl (0.3.0) lib/rabl/engine.rb:28:in `render'
How can I get an array as my root object (instead of {})?
I figured out a way to do it for my API using collections, but it is a bit of a hack…
Hi, I'm having a little trouble wrapping my head around how to use partials and extends correctly. I have a list of people, and I'd like to include pagination info with the JSON, so my frontend can tell what page I'm on, and get to the next/previous page of data.
my json.rabl file looks like this:
object false
child(@people => :entries) do
attributes :id, :first_name
end
node(:pagination) do
{
:url => @pagination_url,
:current_page => @people.current_page,
:per_page => @people.per_page,
:total_entries => @people.total_entries
}
end
I'd like to push the pagination section into a shared partial, and possibly call it like this:
object false
child(@people => :entries) do
attributes :id, :first_name
end
partial "shared/pagination", :object => @people, :url => @pagination_url
That doesn't work. I've been struggling to land at the correct syntax to do this.
..and then have the shared/pagination.json.rabl look like this:
node(:pagination) do
{
:url => url,
:current_page => object.current_page,
:per_page => object.per_page,
:total_entries => object.total_entries
}
end
I guess my question is, how do I get where I want to be using rabl? I'd be happy to add a wiki entry to further explain partials and extends.. that is, after I understand how they work. Thanks!
Add a Railtie and support Rails 3 projects.
This should be easy. I already have a hash compiled, might be as easy as invoking to_xml and making sure it looks OK.
It's possible use custom JSON encoding engin in rabl?
Why it's needed? Cyrillic renders in JSON like this (6 symbols for 1):
yajl gem (https://github.com/brianmario/yajl-ruby) solve this problem.
Hello,
maybe it is not Rabl question, but I have no more place to ask this.
I have three models: user, user_item, and item. User can buy items, user's items store in user_item model. If user buys some item 20 times, there would be 20 similar records in user_items table.
code(:num) do |e|
current_user.items.include?(e) ? current_user.items.all.count(e) : 0
end
So, I render only unique items and field :num with quantity on items, like:
items: [
{item1: {title: "xxx", num: 20}}
{item1: {title: "yyy", num: 10}}
]
This is hacky a bit, but it works.
But one more problem: I have Block (like a category), Mission (it's a little game) and every mission have one or more required items. And I should render only unique required items per mission, and I do not know, how to do this. This is how I do this:
# controller
def blocks
@blocks ||= Block.includes(:missions => [ :requirement_items ])
end
# view
object false
child blocks do
attributes :id, :title
child :missions do
attributes :id, :title
child :requirement_items => :requirements do
attributes :id, :title
# What will be here?
end
end
end
I wish you will help me, because I've already spent some days to complete this ;(
Thank you again for your awesome gem!
I have
[{"person":{"id":1,"firstname":"Zaphod","lastname":"BEEBLEBROX","gender":"Mr"}},{"person":{"id":2,"firstname":"Ford","lastname":"PREFECT","gender":"Mr"}}]
But i would like
[{"id":1,"firstname":"Zaphod","lastname":"BEEBLEBROX","gender":"Mr"},{"id":2,"firstname":"Ford","lastname":"PREFECT","gender":"Mr"}]
it's possible ?
I have builder template index.json.rabl for People#index controller with
attributes :id, :firstname, :lastname, :gender
and the collection of objects => @people
In the backbone.js FAQ, Jeremy suggests bootstrapping a backbone.js model by using ERB and converting the object/collection to json:
<script>
Accounts.refresh(<%= @accounts.to_json %>);
Projects.refresh(<%= @projects.to_json(:collaborators => true) %>);
</script>
http://documentcloud.github.com/backbone/#FAQ-bootstrap
How could I render a rabl template in the view instead of calling to_json on the object/collection?
Hi,
Sorry, I should be able to do this, I think - the flash object is a collection of arrays - each of which are tuples, [name_symbol, message_string] - I tried this, but nothing is coming out - is there a debug mode that logs errors? Again I am using it in the context of "object false"
child @flash do |n,m|
attributes n, m
end
and this:
child @flash do
attributes :msg, :name
end
Thanks,
Chris
Here is my rabl view.
collection @lines => :lines
attributes :title, :description
code :id do |line|
line.account.name+"-"+line.title
end
and the response is:
{"lines"=>
[{"title"=>"private-line", "description"=>"Et pariatur eos eaquptas enim.", "id"=>"wliTa-private-line"},
{"title"=>"public-line", "description"=>"This line can be viewed publicly", "id"=>"wliTa-public-line"}]
}
I want the id
attribute to be at first attribute like below:
{"lines"=>
[{"id"=>"wliTa-private-line", "title"=>"private-line", "description"=>"Et pariatur quae voluptas enim."},
{"id"=>"wliTa-public-line", "title"=>"public-line", "description"=>"This line can be viewed publicly"}]
}
Is this doable or any other solution to get this order of response?
Tried to use rabl with Rails 3.1.0.rc1, raises
undefined method `copy_instance_variables_from' for #<Rabl::Engine:0x000001025671d0>
That method has been removed from Active Support:
rails/rails@c208385
i.e.,
response should look like:
some_function({"lat":41.067995459995,"lon":28.944897651672})
is that possible?
Rails allow to add view paths, so fetch_source may not work correctly, for example:
From config:
ActionController::Base.view_paths << 'app/views/mobile'
app/views/mobile/offers/show.json.rabl
:
collection @offers
extends 'offers/show'
Solution is use find_template internal Rails method.
Hey I have something that looks like of like
collection @tours
attributes :created_at, :days_required, :description, :fee_description, :fee_scale, :id, :name, :published, :updated_at, :lat, :lng
attribute :small_image_url do |url|
root_url + url
end
attribute :large_image_url do |url|
root_url + url
end
I'm trying to modify the :large_image_url and :small_image_url to add the root_url to it. I'm working in rails 3. I think I might be confused on what functionality is available or how to do this.
Right now Tilt Engine always renders to JSON. Check the 'scope' format and use that to determine the format to render (xml or json)
Tilt template registration is hacked together right now. It works but needs some love: https://github.com/nesquena/rabl/blob/master/lib/rabl/register.rb
index.json.rabl
:
collection @offers
attributes :id, :title, :price, :permalink
child :metro_station do
attributes :name
end
show.json.rabl
:
object @offer
attributes :id, :title, :price, :permalink
child :metro_station do
attributes :name
end
index.json.rabl
:
collection @offers
render 'show'
show.json.rabl
:
object @offer
attributes :id, :title, :price, :permalink
child :metro_station do
attributes :name
end
I don't sure about syntax, but I hope you are got idea. Thanks.
I have a tour controller that has this in it:
respond_to :json
def show
@tour = Tour.find_by_id_and_published(params[:id], true)
if @tour.nil?
respond_with(:error)
else
end
end
(these isn't finished yet... so ya know...)
When I try to access a tour that doesn't exist, it still tries to render the rabl view, throwing a error. I don't know if my logic is wrong here but shouldn't it respond back with a 404 error with empty json or something like that?
Hey I'm back.
I have something that looks like this
class Location < ActiveRecord::Base
#Associations
has_many :photos
end
class Photo < ActiveRecord::Base
# Assoications
belongs_to :location
end
Now a location does not have to have a photo, but can have many. In the situation where the location doesn't have any photo objects created, the json output looks like this.
"array": []
Now if I do have a photo created it shows up like this
"location": {
"name": "grand canyon store",
"description": "grand canyon store is a way awesome place",
"location_type": "museum",
"lat": 39,
"lng": -111,
"address": null,
"city": null,
"state": null,
"postal_code": null,
"phone": null,
"email": null,
"url": null,
"fee_scale": 1,
"fee_description": null,
"availability_description": null,
"created_at": "2011-05-20T22:12:11Z",
"updated_at": "2011-05-20T22:12:11Z",
"photos": [
{
"name": "sweet canyon photo",
"small_image_url": "http://tour_builder.dev/uploads/photo/image/2/small_test.gif",
"large_image_url": "http://tour_builder.dev/uploads/photo/image/2/large_test.gif"
}
]
My rabl code looks like this
child :photos do
attribute :name
node :small_image_url do |photo|
@root_url + photo.small_image_url
end
node :large_image_url do |photo|
@root_url + photo.large_image_url
end
end
end
If there aren't any photos, the photos array should just be empty. Something like photos[] vs array[]
Add Tilt support if Tilt is found (for Padrino/Sinatra support)
On a project and template basis, there needs to be configuration. Namely,
users : { ... }
And probably others I can't think of right now.
I am using RSpec and in my controller specs I noticed that rabl views are still being rendered - usually rendering views with a template are stubbed in such examples ("By default, controller specs stub views with a template that renders an empty string instead of the views in the app." [1]).
I hacked that back into my specs manually with
ActionView::Template::Handlers::Rabl.stub(:call).and_return('')
Just wondering if there is a better way? Could this also be a bug on RSpec side, i.e. shouldn't it hook into the template renderers itself automatically, given it is possible?
Thanks again!
[1] http://relishapp.com/rspec/rspec-rails/v/2-6/dir/controller-specs/views-are-stubbed-by-default
in builder.rb line 73, include_root should be false when rendering xml, but I'm not sure the best way to persist the desired output format through the various child calls.
I see that you can set include_json_root = false
in an initializer so you don't get the root node at every level, but is is possible to only disable the root node for a particular child node and in a particular template? So instead of rendering a collection of objects as follows :-
{ "myObjects" :
[
{ "myObject" : { "keyOne" : "valueOne", "keyTwo" : "valueTwo" } },
{ "myObject" : { "keyOne" : "anotherValueOne", "keyTwo" : "anotherValueTwo" } }
]
}
I want something like this :-
{ "myObjects" :
[
{ "keyOne" : "valueOne", "keyTwo" : "valueTwo" },
{ "keyOne" : "anotherValueOne", "keyTwo" : "anotherValueTwo" }
]
}
If I have:
object @user
Allow the root node to be configurable:
object @user => :person
or:
object @users => :people
Also support a collection syntax:
collection @users => :people
partial() and extends() don't work in Sinatra because the internal method fetch_source() relies on either Rails or Padrino to resolve the path for the views directory. I had to monkey-patch that method in my Sinatra app:
module Rabl
module Helpers
def fetch_source(file, options={})
file_path = Dir[File.join(APP_ROOT, 'views', file + "*.rabl")].first
File.read(file_path) if file_path
end
end
end
.. Where APP_ROOT is a constant I defined in my app.
Is there a better way?
I see that you've bumped the gem to 0.3.0. I'd love to see a change log in the root directory to see if what's changed and if there are any breaking changes I need to know about before upgrading.
Thanks!
Hi,
I'm unsure if this is an application-specific problem, or what, but with my app I'm trying to use rabl and running into a snag.
So i have the following controller:
class PeopleController < ApplicationController
def show
@person = Person.find(params[:id])
respond_to do |format|
format.html
format.json
end
end
end
My show.json.rabl file looks like this:
object @person
attribute :id
My app/views/layouts/application.rhtml file looks like this:
<html>
<body>
<%= yield :main if @content_for_main -%>
</body>
</html>
Now, when I attempt to get /people/1.json, I do not see the json. I see html!
GET /people/1.json
<html>
<body>
</body>
</html>
The rails log looks like this:
Processing PeopleController#show to json (for 127.0.0.1 at 2011-07-01 11:03:00) [GET]
Parameters: {"id"=>"1"}
Person Columns (44.9ms) SHOW FIELDS FROM `people`
Person Load (0.7ms) SELECT * FROM `people` WHERE (`people`.`id` = 1)
Rendering template within layouts/application
Rendering people/show
Lead Columns (14.4ms) SHOW FIELDS FROM `people`
Completed in 173ms (View: 30, DB: 77) | 200 OK [http://localhost/people/1.json]
so it looks to me like rails is attempting to show json, but ends up rendering html. I'm confused.
If I explicitly tell the controller to not render a layout, then it shows the json no problem:
class PeopleController < ApplicationController
def show
@person = Person.find(params[:id])
respond_to do |format|
format.html
format.json { render :layout => false }
end
end
end
That works. Unfortunately I do not know rails views that well, otherwise I'd have submitted a patch with my issue. But can you guys think why my app is doing this?
Thanks in advance!
Great gem thanks. Is there a way to use an arbitrary ruby object (as opposed to an active model) as the root object? I hacked round it for the time being by adding a 'valid?' method to my class.
Cheers
I am using pagination, so I need to render all my users like an array, and then add to the results some pagination params (like :per_page, :current_page and :pages_count). Any suggestions how to do this?
Thanks.
Add access to view helpers from RABL. In Rails or Padrino, support loading all helper methods into template.
# example.rabl
node :example do |foo|
strip_tags(foo.value)
end
Hi all.
I'm working in rails 3 with rabl (obviously) and I'm trying to create some json to reflect the following database structure.
class Tour < ActiveRecord::Base
#Associations
belongs_to :provider
has_many :tour_stops
end
class TourStop < ActiveRecord::Base
#Associations
belongs_to :tour
belongs_to :location
has_one :route_starting_here, :class_name => "TourRoute", :foreign_key => "start_id"
has_one :route_ending_here, :class_name => "TourRoute", :foreign_key => "end_id"
end
class Location < ActiveRecord::Base
#Associations
has_many :photos
has_many :tour_stops
has_one :video
belongs_to :provider
end
class TourRoute < ActiveRecord::Base
#Associations
belongs_to :end, :class_name => "TourStop"
belongs_to :start, :class_name => "TourStop"
end
Note: I left out validations etc cause they aren't relevant for this ticket.
What I have created is something like looks kind of like this:
*show.json.rabl
object @tour
attributes :created_at, :days_required, :description, :fee_description, :fee_scale, :name, :published, :updated_at, :lat, :lng
node :small_image_url do |tour|
@root_url + tour.small_image_url
end
node :large_image_url do |tour|
@root_url + tour.large_image_url
end
child :tour_stops do
attributes :position, :updated_at, :created_at
child :location do
attributes :name, :description, :location_type, :coords, :address, :city, :state, :postal_code, :phone, :email, :url, :fee_scale, :fee_description, :availability_description, :created_at, :updated_at
end
end
Note: This isn't 100% complete but it demonstrates the issue i'm running into.
When I try to grab json output I get this error:
"stack level too deep"
I believe this is because a :location is not the child of tour_stop but the parent of tour_stop. However not sure. Should there be a "parent" method as well as a "child" method?
Perhaps there is a way to do this with the current rabl, but I'm unsure as of now.
Thanks for the help.
Hi,
I am probably doing this wrong, but I have a method that wants to return a collection and a status, so I am making my data object sort of like this:
@thing = {:foo => "bar", :pop => 123}
So, my rabl template is
attributes :foo, :pop
Hoping to get
{ "foo" : "bar", "pop" :123}
But was getting this under last night's version:
{ "pop":"bar", "pop":123}
Today I get an error:
undefined method `to_html' for #<Rabl::Engine:0x1075c0730>
Perhaps I should be using the "object false" route...
Thanks,
Chris
PS Tried to add tests/fix it - seems that the problem is the attribute method can be passed a hash of options and its confusing the object hash as options:
https://github.com/kimptoc/rabl/commit/dc3be6eba6389998614f7cb846240aebcc2062ef
Hi
It would be nice if there was a wiki to post how tos etc.
I can't seem to get rabl to work with sinatra, can you provide an example, perhaps in the wiki?
Don't know if there's a Google Group or anything, so I'm just posting here.
I've been working on a REST API for a Rails app for the past 2 months and just discovered rabl
.
It might be something I've been looking for.
Converted a few resources from as_json
to .json.rabl
and it seems cool so far.
I've got a few questions/ideas.
@object
template from a @collection
template?I've got a posts
resource and want to re-use the show
template in the index
template vibratim.
Here's what I've come up with:
posts/show.json.rabl
:
object @post
attributes :id, :body
posts/index.json.rabl
:
collection @posts
extends 'posts/show'
It seems clumsy, but it works. I was kind of expecting a partial
somewhere here. What would be the proper way to do that?
if
s within a templateInstead of the :if => lambda { ... }
pattern, I tried using regular if
s within a template:
posts/show.json.rabl
object @post
attributes :id, :body
if @post.published?
code(:publisher) { |p| p.publisher.username }
end
This works also, but presents a problem when using extends
as presented above. The controller for an index
action only provides the @posts
collection, so the @post
is nil and the if
always fails when rendering the index
action.
I think it would be cleaner to use regular if
s. Especially when adding multiple custom fields - this would just be a single if
block instead of multiple code(:field, :if => lambda { ... repeating condition ... })
blocks.
Maybe the way to do it could be - instead of relying on instance variables, provide an object
or collection
helper, which can always access the current object? Kind of like RSpec utilises subject
.
child
elementsI needed to include an entire subresource based on a condition. This didn't work:
child(:user, :if => lambda { ... }) do
...
end
So I eventually went with:
code(:user, :if => lambda { ... }) do |p|
{
:id => p.user.id,
:username => p.user.username
}
end
This works, but breaks DRY
. I have a users/show.json.rabl
with properly defined attributes, and would like to re-use it here. How would I go about it?
All in all, thanks for the great work.
These are just some of my thoughts, Markdown-formatted.
I'd be glad to dig into the code if you see any point in my mumbling ;)
Cheers!
I set a debug point on line 55 of lib/rabl/template.rb. When I template.inspect
I get "app/views/attendee/show.rabl" which is correct, but template.source
returns and empty string.
If I then do File.open(Rails.root + template.inspect, 'r') { |f| puts f.read }
that produces:
extends("attendee/base")
object @attendee
app/views/attendee/base.rabl
attributes :oid, :first_name, :last_name
I am setting @Attendee in my show action and I can not figure out why the rendered result is:
{"attendee": {}}
Hey,
I'm not sure if this is the expected behavior but it threw me off a little bit when I first ran into it so I thought I would post it here.
I have a tour_stop that has two tour_routes. This is what my models look like.
class TourRoute < ActiveRecord::Base
#Associations
belongs_to :end, :class_name => "TourStop"
belongs_to :start, :class_name => "TourStop"
end
class TourStop < ActiveRecord::Base
#Associations
belongs_to :tour
belongs_to :location
has_one :route_starting_here, :class_name => "TourRoute", :foreign_key => "start_id"
has_one :route_ending_here, :class_name => "TourRoute", :foreign_key => "end_id"
end
Ok cool. Now in my awesome api::tour view I have something like this
object @tour
attributes :created_at, :days_required, :description, :fee_description, :fee_scale, :name, :published, :updated_at, :lat, :lng
node :small_image_url do |tour|
@root_url + tour.small_image_url
end
node :large_image_url do |tour|
@root_url + tour.large_image_url
end
child :tour_stops do
attributes :position, :updated_at, :created_at
child :location do
attributes :name, :description, :location_type, :lat, :lng, :address, :city, :state, :postal_code, :phone, :email, :url, :fee_scale, :fee_description, :availability_description, :created_at, :updated_at
end
child :route_starting_here do
attribute :route
end
child :route_ending_here do
attribute :route
end
end
The part to look at here, is the child :route_starting_here portion. If I leave it as is, the json produced looks like this
{
"tour": {
"created_at": "2011-05-20T22:01:37Z",
"days_required": null,
"description": "This is the description for the grand canyon tour",
"fee_description": null,
"fee_scale": 1,
"name": "Grand Canyon Tour",
"published": true,
"updated_at": "2011-05-20T22:01:37Z",
"lat": 39,
"lng": -111,
"small_image_url": "http://tour_builder.dev/uploads/tour/image/1/small_test.gif",
"large_image_url": "http://tour_builder.dev/uploads/tour/image/1/large_test.gif",
"tour_stops": [
{
"tour_stop": {
"position": 1,
"updated_at": "2011-05-20T22:12:39Z",
"created_at": "2011-05-20T22:12:39Z",
"location": {
"name": "grand canyon store",
"description": "grand canyon store is a way awesome place",
"location_type": "museum",
"lat": 39,
"lng": -111,
"address": null,
"city": null,
"state": null,
"postal_code": null,
"phone": null,
"email": null,
"url": null,
"fee_scale": 1,
"fee_description": null,
"availability_description": null,
"created_at": "2011-05-20T22:12:11Z",
"updated_at": "2011-05-20T22:12:11Z"
},
"tour_route": {
"route": {
"type": "LineString",
"coordinates": [
[
0,
0
],
[
1,
1
],
[
2,
1
],
[
2,
2
]
]
}
}
}
}
]
}
}
Notice that tour_route is not being named :tour_starting_here.. it's being named "tour_route". In order for me to get it named correctly to :tour_starting_here I need to set it's alias like ...
child :route_starting_here => :route_starting_here do
attribute :route
end
Which will correctly produce
"route_starting_here": {
"route": {.......... other stuff blah blah blah
Shouldn't this all ready know that I named this route_starting_here? It seems like it's pulling from the class name to set the name vs the association name which imo would make more since. Anyway, just a thought. Thanks for any input.
For this example
class PostsController < ApplicationController
def index
@posts = Post.all
respond_to do |format|
format.json
end
end
def show
@post = Post.find(params[:id])
respond_to do |format|
format.json
end
end
end
With collection template index.json.rabl it's not necessary declare the collection
attributes :id, :title, :content
But in object template show.json.rabl the declaration it's necessary.
object @post
attributes :id, :title, :content
otherwise the { } it's empty
It's normal way ?
when I do:
object @users
attributes :id, :name
I get a collection similar to
[
{
"user": {
"id": "...",
"name": "...."
}
},
{
"user": {
"id": "...",
"name": "...."
}
},
{
"user": {
"id": "...",
"name": "...."
}
}
]
Is there a way to return the results in the more standard format:
"users": [
{
"id": "...",
"name": "..."
},
{
"id": "...",
"name": "..."
},
{
"id": "...",
"name": "..."
}
]
The latter format is understood better by ExtJS data store.
sort of a low priority bug, however I noticed that object @users will iterate over @users twice.
This is noticeable in ORMs that return criteria objects that execute the query on iteration (such as mongoid). So the query actually gets executed twice.
Probably something to watch for and maybe add a unit test for it at some point. Not a huge deal since I can do to_a
on the object before rendering it to rabl.
I'm rather confused what's going on. I'm trying to do the example and I get this for a result
[{},{},{}]
Here's my controller
def index
@courses = Course.all
respond_to do |format|
format.json
end
end
Here's my index.rabl template
collection @courses
attributes :id, :title
However, my show action works great.
My controller:
def show
@course = Course.find(params[:id])
respond_to do |format|
format.json
end
end
My show.rabl template:
object @course
attributes :title, :id
I'm using Rails 3.0.7 and Ruby 1.9.2-p180-patched. How would I test this to see what's going on?
Thanks!
Hi,
I dont suppose there is a way to exclude values if they are nil/null?
Guess I can add an if condition in the template, but wondering if there is a global option to do this...
Thanks,
Chris
Hey guys,
Has anyone else noticed that some rabl views can take very long to render? I have API endpoints with 1800ms time in the view and just 226ms with ActiveRecord. I'm using Rails 3.1.0.rc4 by the way, but I also tried this with Rails 3.0.9 with similar results.
Peter
Hello, when tried to use rabl in padrino just to add it to Gemfile it does not register as templating engine. It is solved when put gem 'rabl' after gem 'padrino' (which is last by default) in Gemfile. When I put breakpoint in rabl.rb:14 Padrino is not yet defined there. Do you think it is a problem?
Pepe
I've been converting an API that used to_json over to RABL and one quirk that I've run into is the way in which the root names of items in a collection are determined. For instance, consider the following RABL template:
collection @fields
attributes :name, :id, :value
Where @fields is a collection of entities which use single table inheritance:
class Field < ActiveRecord::Base; end
class AddressField < Field; end
class EmailField < Field; end
When serializing to JSON using #to_json, I get something like:
[
{"email_field": {"name":"Work Email", "id":1234, "value":"[email protected]"}},
{"address_field": {"name":"Home Address","id":12345,"value":"123 Fake St."}}
]
But when serializing using the RABL template, the root node names are always determined by the first item in the collection:
[
{"email_field": {"name":"Work Email", "id":1234, "value":"[email protected]"}},
{"email_field": {"name":"Home Address","id":12345,"value":"123 Fake St."}}
]
I think the simplest fix here would be to change https://github.com/nesquena/rabl/blob/master/lib/rabl/engine.rb#L34 so that the object_name is computed for each item in the collection. I'm going to give that a try locally, but wanted to see if anyone had a better approach.
Example:
From app/models/offer.rb
:
has_many :offer_images do
def history_image(size = :history)
history.first.try(:image).try(:url, size)
end
end
From app/views/offers/show.json.rabl
:
child :offer_images do
node(:thumb) { |i| i.history_image(:small_thumb) }
node(:normal) { |i| i.history_image(:small_promo) }
end
I am sloppy, add more riot unit testing
But 1.9.2 is fine, because ree Hashes is not ordered.
rabl : rake test
(in /Users/koss/Code/rabl)
/Users/koss/.rvm/rubies/ree-1.8.7-2011.03/bin/ruby -I"lib:lib:test" -rubygems "/Users/koss/.rvm/gems/ree-1.8.7-2011.03@global/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/builder_test.rb" "test/configuration_test.rb" "test/engine_test.rb" "test/template_test.rb"
.............................................F......................
FAILURE
Rabl::Engine with defaults #glue asserts that it glues data from a child node => expected "{\"user\":{\"name\":\"leo\",\"city\":\"LA\",\"age\":12}}", not "{\"user\":{\"city\":\"LA\",\"name\":\"leo\",\"age\":12}}"
(on line 162 in ./test/engine_test.rb)
67 passes, 1 failures, 0 errors in 0.039941 seconds
rake aborted!
Command failed with status (1): [/Users/koss/.rvm/rubies/ree-1.8.7-2011.03/...]
(See full trace by running task with --trace)
My favorite solution is hash hash.to_s.split('').sort
:
asserts "that it glues data from a child node" do
...
end.split('').sort.equals "{\"user\":{\"name\":\"leo\",\"city\":\"LA\",\"age\":12}}".split('').sort
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.