In this example you can learn how to use a custom Ruby on Rails data source with JayData, without the need to write an own provider. You can download this Rails and JayData projects and setup your local development environment.
Ruby on Rails
We will create the server-side Ruby on Rails application and generate the following basic files:
1 2 3 4 5 6 |
$ rails new shop $ cd shop $ rails generate model Category name:string description:text --skip-timestamps $ rails generate controller Categories index show $ rails generate model Product category_id:integer product_name unit_price:float units_in_stock:integer discontinued:boolean --skip-timestamps $ rails generate controller Products index show |
Create and seed the database. In the nw.sql you can find the Categories and Products table of the Northwind database (the DB creation script can be found in the rails_demo/public folder inside YQLWithRails.zip, so save the nw.sql to the parent directory).
1 2 |
$ rake db:migrate $ sqlite3 db/development.sqlite3 < ../nw.sql |
Modify the app/controllers/categories_controller.rb file by adding XML response:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class CategoriesController < ApplicationController def index @categories = Category.all respond_to do |format| format.xml { render xml: @categories, skip_types: true, dasherize: false } end end def show @category = Category.find(params[:id]) respond_to do |format| format.xml { render xml: [ @category ], skip_types: true, dasherize: false } end end end |
Do the same in the app/controllers/products_controller.rb file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class ProductsController < ApplicationController def index conditions = [] unless (params[:category_id].blank?) conditions.push('category_id = ?', params[:category_id]) end @products = Product.find(:all, conditions: conditions) respond_to do |format| format.xml { render xml: @products, skip_types: true, dasherize: false } end end def show @product = Product.find(params[:id]) respond_to do |format| format.xml { render xml: [ @product ], skip_types: true, dasherize: false } end end end |
In the config/routes.rb replace the generated rules:
1 2 3 4 |
get "products", to: 'Products#index', format: :xml get "products/:id", to: 'Products#show', format: :xml get "categories", to: 'Categories#index', format: :xml get "categories/:id", to: 'Categories#show', format: :xml |
Now you can try out what we have so far. Start the development webserver:
1 |
$ rails server |
In a different console, watch the results:
1 2 3 4 5 |
$ curl http://localhost:3000/categories --header 'Accept: application/xml' $ curl http://localhost:3000/categories/3 --header 'Accept: application/xml' $ curl http://localhost:3000/products --header 'Accept: application/xml' $ curl http://localhost:3000/products?category_id=3 --header 'Accept: application/xml' $ curl http://localhost:3000/products/3 --header 'Accept: application/xml' |
YQL
Publish your application to a public location where Yahoo can access it. The following two files define the Categories and Products tables. (See Open Data Tables Reference):
public/products.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?xml version="1.0" encoding="UTF-8"?> <table xmlns="http://query.yahooapis.com/v1/schema/table.xsd"> <meta> <author>JayData, community@jaydata.org</author> </meta> <bindings> <select itemPath="products.product" produces="XML"> <inputs> <key id="id" type="xs:int" paramType="path" required="false" /> <key id="category_id" type="xs:int" paramType="query" required="false" /> </inputs> <urls> <url><![CDATA[http://jaydata.org/examples/rails/products/{id}]]></url> </urls> <execute> <![CDATA[ response.object = request.accept('application/xml').get().response; ]]> </execute> </select> </bindings> </table> |
public/categories.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?xml version="1.0" encoding="UTF-8"?> <table xmlns="http://query.yahooapis.com/v1/schema/table.xsd"> <meta> <author>JayData, community@jaydata.org</author> </meta> <bindings> <select itemPath="categories.category" produces="XML"> <inputs> <key id="id" type="xs:int" paramType="path" required="false" /> </inputs> <urls> <url><![CDATA[http://jaydata.org/examples/rails/categories/{id}]]></url> </urls> <execute> <![CDATA[ response.object = request.accept('application/xml').get().response; ]]> </execute> </select> </bindings> </table> |
Another environment file (public/tables.env):
1 2 |
use 'http://jaydata.org/examples/rails/categories.xml' as categories; use 'http://jaydata.org/examples/rails/products.xml' as products; |
Now you can try it in the developer console: http://developer.yahoo.com/yql/console/?env=http://jaydata.org/examples/rails/tables.env
JayData
Everything is ready to use JayData to access our tables from JavaScript. Define the entities and context:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
$data.Entity.extend('NorthwindModel.Category', { 'id': { key: true, type: 'integer', nullable: false, computed: true }, 'name': { type: 'string', nullable: false, required: true, maxLength: 15 }, 'description': { type: 'string', nullable: true, maxLength: Number.POSITIVE_INFINITY }, 'products': { type: 'Array', elementType: 'NorthwindModel.Product', inverseProperty: 'category' } }); $data.Entity.extend('NorthwindModel.Product', { 'id': { key: true, type: 'integer', nullable: false, computed: true }, 'category_id': { type: 'integer', nullable: true }, 'product_name': { type: 'string', nullable: false, required: true, maxLength: 40 }, 'unit_price': { type: 'number', nullable: true }, 'units_in_stock': { type: 'integer', nullable: true }, 'discontinued': { type: 'boolean', nullable: false, required: true }, 'category': { type: 'NorthwindModel.Category', inverseProperty: 'products' } }); $data.EntityContext.extend('JayDataExamples.NorthwindDB.NorthwindEntities', { Categories: { type: $data.EntitySet, elementType: NorthwindModel.Category, tableName: 'categories' }, Products: { type: $data.EntitySet, elementType: NorthwindModel.Product, tableName: 'products' } }); var northwind = new JayDataExamples.NorthwindDB.NorthwindEntities({ name: 'YQL', YQLEnv: "http://jaydata.org/examples/rails/tables.env" }); |
Select cheap products:
1 2 3 4 5 6 7 |
northwind.Products .where(function (p) { p.unit_price < 10 }) .toArray(function(cheapProducts) { for (var i = 0; i < cheapProducts.length; i++) { console.log(cheapProducts[i].product_name) } }); |
Console:
1 2 3 4 5 6 7 8 9 10 11 |
Konbu Teatime Chocolate Biscuits Tunnbröd Guaraná Fantástica Geitost Jack's New England Clam Chowder Rogede sild Zaanse koeken Filo Mix Tourtičre Rhönbräu Klosterbier |