Wednesday, October 27, 2010

Create a Rhodes application which will sync data from rails application using Rhosync

In this blog we will create a Rhodes application which will synchronize your data from rails application through Rhosync.
We need to create 3 applications
  1. Rails Application: It will feed data in json or XML format.
  2. Rhodes Application: This code will be installed in mobiles.
  3. Rhosync Application: These will sync the data from rails App to Rhodes Application in your phone
Steps to create rails Application:
I will just create a rails application using scaffold:
  1. rails employee_details
  2. cd employee_details
  3. Ruby script/generate scaffold employee name:string phno:integer address:text
  4. Update your database.yml 
  5. Rake db:migrate
  6. Add these code in your employees controller (you can skip this step if you want to only show employee details and does not do crud operations.)
              protect_from_forgery :except => [:create, :update, :delete]
    
    7. Add this line under response in controller:
             
             format.json { render :json => @employee }

    8. Once it is done we will run it on port 3000:

              http://localhost:3000\employees.json

         we will get output in json format.


Steps to create Rhodes application:
  1. Rhogen app employee
  2. Cd employee
  3. Rhogen model employee name,phno,address
  4. Add link in index.erb to your index page
  5. Enable sync in model Employee  
                enable :sync


    6.   Edit rhoconfig.txt file and set
             syncserver = 'http://localhost:9292/application
    7.    rake run:bb


Steps to create Rhosync application:
  1. Rhosync app employee_server
  2. Rhosync source employee
  3. Then employee.erb incude json and rest client
          require 'json'
          require 'rest_client'

     4. Update the query method

  def query(params=nil)
    parsed=JSON.parse(RestClient.get("http://localhost:3000/employees.json").body)
    @result={}
    parsed.each { |item|@result[item["employee"]["id"].to_s]=item["employee"] } if parsed
    @result
  end

Now you can test this by login to your simulator.





29 comments:

  1. can this work for any simulator

    ReplyDelete
  2. Rails and Rhosync application will be same for all devices.

    In Rhodes application
    > for Android/ Iphone U have to add link in index.erb and for Blackberry add link in index.bb.erb

    For Android instead of using localhost use your ipaddress because android simulator in not able to connect with localhost.

    ReplyDelete
  3. Hi i am new to rhodes , i am not getting your step 4 . Add link in index.erb to your index page . what it means , what is index page here . can u give the example line .

    ReplyDelete
  4. If you start your Rhodes application by default index page(This file is in app folder) is loaded. We have to add a link to Employee index page. If you are using Iphone or Andorid you have to add the link in index.erb and if you are using Blackberry do it index.bb.erb.

    ReplyDelete
  5. Thanks for response i got your point and successfully implemented this tutorial on my local system . I liked your tutorial, Thank you very much again.

    ReplyDelete
  6. hi, abhishek

    When i logging in with first user(say A) to my client the sync process works fine(all data sync properly to device.) . but when after logged out of A ,when i tried to login with another user(B) the sync process does not seems to work. Is there any restriction for sync server that on one client is dedicated to only one user that has been logged first after installation of app on device . If not then what i am doing wrong please let me know . my environment is "Development" and data partition is "user" . Thanks in advance.

    ReplyDelete
  7. Hi Raj,
    If you have not implement any authentication then it should work. You have written the sync code in query method right?(If your source adapter is user then put your sync code in query method of user.rb)

    Note: If you have access Rhosync for more then 10 different user then you have to reset user from rhosync web console.

    ReplyDelete
  8. Hi abhishek,

    There is no authentication on user ,also i wrote all the sync adapter correctly(that is why it is working for user A). My rhosync server has only two users .

    After logout of User A , when i reinstalled the app and tried to login with user B then sync data is working fine for user B as well . I am not sure whether i have to reset the user preference and delete the existence of first user from the client on call of "on_sync_user_changed" . If is this the case then please tell me how to clear my first user existence from the client before login with other user.

    ReplyDelete
  9. I think it should have work. I checked, it is working good in my application.
    However you can right following line in logout action:
    Rhom::Rhom.database_fullclient_reset_and_logout

    ReplyDelete
  10. No luck abhishek .Not working ..

    ReplyDelete
  11. I have a question regarding data base query in rhodes app . I have one model called Element. When i doing query as :

    Element.find(:all,:conditions=>
    {
    {
    :name => "form_id",
    :op =>"IN"
    } => [1,2,3]
    }
    )
    above query works fine (Here form_id is one of column in Element model).

    But when i tried to search all the element on basis of :object column . always it return [] , although data is available corresponding these objects i.e

    Element.find(:all,:conditions=>
    {
    {
    :name => "object",
    :op =>"IN"
    } => [4,5,6]
    }
    )

    What i am doing wrong . Is the any other way to above query .

    ReplyDelete
  12. I also tried this is not working.. Even I tried :
    Element.find(:all,:conditions=>
    {
    {
    :name => "object",
    :op =>"="
    } => "4",
    {
    :name => "object",
    :op =>"="
    } => "5",
    {
    :name => "object",
    :op =>"="
    } => "6",
    } ,
    :op =>"or"

    )


    This also is not working for object but working for other fields. I think you are also using property bag..This seem a bug for property bag schema...

    I have raised this issue on Rhomobile groups http://groups.google.com/group/rhomobile/browse_thread/thread/6aa1415b2c166415

    Let see if they can find out some solution for us.

    ReplyDelete
  13. right, abhishek its seems to be bug for propertybag.

    Thanks for raising this issue to rhomobile group . I am waiting for responses.

    ReplyDelete
  14. Do you have any idea how to use Multiple select box in rhodes app . If you know the syntax then please let me know . Following syntax is not working.

    ReplyDelete
  15. Multiple select box is HTML part.It is not releated to Rhodes. So If the device support that HTML/JS then Rhomobile also support that.

    Which device you are using? If you are using Blackberry it has lot limitation which you can check at: http://docs.blackberry.com/en/developers/deliverables/1143/browser_devguide.pdf

    ReplyDelete
  16. You are right but all other HTML control is working for me except multiple select box .I am using android . Also In the rhodes Doc section i did not find any thing about multiple select box.

    ReplyDelete
  17. What code you are using for multiple select box?
    If you don't have much options you can use checkbox.

    ReplyDelete
  18. I am using simple HTML code for multiple select box.

    ReplyDelete
  19. I think there is issue with Multiple select box for Android:
    http://stackoverflow.com/questions/5654140/html-select-multiple-in-android-renders-weird

    ReplyDelete
  20. Yes Abhishek , there is issue in android with multiple select , temporarily i used checkbox as alternative.

    ReplyDelete
  21. Hi Abhishek ,

    I am submitting a form , I has different types of controls like date filed , time field , camera , signature and many more . My issue is that when filling the form if control goes out from the form(i.e if i opt to select time or date or signature) ,the form refreshes and all the filled data in form get disappear(user has to fill it again) . In rhodes how can i retain form data in controls if control go out of form.

    Please provide your inputs.

    ReplyDelete
  22. Hi Raj,

    I got your point.. It will happen as we are rendering to another page. I can think of two solution for this :
    1.) You store all parameters in dummy table.
    2.) Pass the values of form to another page as hash of parameters. You have to use lot of JavaScript for this.

    ReplyDelete
  23. Hi Raj
    The issue which you pointed out for object:
    Element.find(:all,:conditions=>
    {
    {
    :name => "object",
    :op =>"IN"
    } => [1,2,3]
    }
    )

    This issue has been fixed and will release with Rhodes version3.1
    Good job you pointing out this issue :)

    ReplyDelete
  24. Hi Abhishek,

    I am using same technique to retain data in form controls ,off-course there is lots of javascript work for this.

    About query issue ,it is good that this problem has been fixed for next release ,do you have any idea when next release is planned for rhodes 3.1 .

    ReplyDelete
  25. Hi Abhishek,
    Can you help me, I am new in Ruby and Rhomobile
    Just started your book and cannot emulate Rails app,
    I have created app and models, but json output is different
    so rhodes app doesn`t take it.
    Here is Rails generated model Controller part:

    def index
    @companies = Company.all

    respond_to do |format|
    format.html # index.html.erb
    format.json { render :json => @companies }
    end
    end

    My json output:

    [{"name":"Tito","created_at":"2012-05-21T15:22:33Z","updated_at":"2012-05-21T15:22:33Z","id":1},{"name":"Noa","created_at":"2012-05-21T15:22:42Z","updated_at":"2012-05-21T15:22:42Z","id":2},{"name":"Afcto","created_at":"2012-05-21T15:22:50Z","updated_at":"2012-05-21T15:23:08Z","id":3},{"name":"Linux","created_at":"2012-05-21T15:22:58Z","updated_at":"2012-05-21T15:22:58Z","id":4},{"name":"Nokia","created_at":"2012-05-23T10:26:01Z","updated_at":"2012-05-23T10:26:07Z","id":5}]

    Your sample output is:
    [{"company":{"name":"Apple","created_at":"2012-04-23T09:04:24Z","updated_at":"2012-04-23T09:07:21Z","id":134}},{"company":{"name":"Google","created_at":"2012-04-22T03:00:26Z","updated_at":"2012-04-22T03:00:26Z","id":102}},{"company":{"name":"Vicco Tee","created_at":"2012-04-24T18:44:43Z","updated_at":"2012-04-24T18:45:22Z","id":143}},{"company":{"name":"Nokia","created_at":"2012-05-01T11:55:00Z","updated_at":"2012-05-01T11:55:00Z","id":159}}]

    ReplyDelete
    Replies
    1. @Artur Instead of changing in Rails you can make small change in Rhosync/Rhoconnect to make it work. You change this line
      parsed.each { |item|@result[item["company"]["id"].to_s]=item["company"]
      by
      parsed.each { |item|@result[item["id"].to_s]=item

      Delete
  26. Hi Abhishek,
    Thank you very much it worked.
    But can you recall how your app was made and what is difference between mine and yours, why different output?
    One more question, why rhoconnect needs some app to feed him info, can it directly connect to some db?

    Thank you
    Artur

    ReplyDelete
    Replies
    1. I have used normal Scaffold to generate a rails app. Syntax for your code also seems fine.
      Yes you can directly connect Rhoconnect with some db in fact you can use redis as your database.

      Delete
  27. wonderful tips you have given..please provide a sample login module in which Rhodes app has to login to the backend application(Rails) and then only user can access Rhodes application..(i.e userid and pass is avail on server)
    i've read the tutorial i.e u have to change in authenticate(username,password,session) fro m application.rb in rhoconnect app. but am not getting the flow of data so i couldnt execute it..please provide a step vise procedure to execute it

    ReplyDelete