Database.com gem Getting Started Article

885 views
Skip to first unread message

Quinton Wall

unread,
Nov 21, 2011, 2:02:52 PM11/21/11
to activesalesforce
Hi all,

Based on the decent amount of traffic asking for pointers on using the database.com gem, it looks like we really need to put together a good getting started article. I'm really pressed for time at the moment and can't write it myself. I was wondering whether any folks on this list are interested in helping out and having it published on the Force.com dev site, and perhaps the Heroku dev site as well.  I will happily assist/edit/be a pain in button reviewer/etc. :)  

There could even be some Heroku & Force.com t-shirts for the author..

Thanks!

Mason Jones

unread,
Nov 21, 2011, 2:08:44 PM11/21/11
to activesa...@googlegroups.com
Sure, I was thinking about writing it up for my own blog anyway, so
depending on the scope of the desired article I'd be interested in
putting something together. I've been working with it for the past
week or so in a proof-of-concept way here, so I'm fairly fresh on what
it's taken to get it going.

Drop me a line and we can discuss!

> --
> You received this message because you are subscribed to the Google Groups
> "ActiveSalesforce" group.
> To post to this group, send email to activesa...@googlegroups.com.
> To unsubscribe from this group, send email to
> activesalesfor...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/activesalesforce?hl=en.
>

Quinton Wall

unread,
Nov 21, 2011, 2:16:53 PM11/21/11
to activesa...@googlegroups.com
awesome. How about a shared google doc to start with?

Jeff Douglas

unread,
Nov 21, 2011, 2:22:32 PM11/21/11
to activesa...@googlegroups.com
Quinton,

I've actually got a video of a preso I did for our internal app dev coe where I build a simple app with the gem. I'm gonna stick it on my blog along with the code at github. I'd be interested in writing an article if no one else volunteers. 

Thanks!

Jeff Douglas
google voice: (941) 227-4843
mobile: (941) 809-3455
email: je...@appirio.com
blog: http://blog.jeffdouglas.com



Appirio, Inc. 
Accelerating On-Demand in the Enterprise
http://www.appirio.com




Joel Dietz

unread,
Nov 21, 2011, 4:43:20 PM11/21/11
to activesa...@googlegroups.com
Thought about this a few times myself. Also have a demo app (or two).

Joel Dietz

unread,
Nov 28, 2011, 6:02:52 PM11/28/11
to activesa...@googlegroups.com
Pushed a sample app to github:

https://github.com/fractastical/databasedotcom-rails-app

Also updated my article on the topic since there was a step or two missing:

Joel Dietz

unread,
Nov 21, 2011, 7:10:33 PM11/21/11
to activesa...@googlegroups.com
Done: http://fractastical.com/2011/11/21/my-first-ruby-on-rails-app-with-the-databasedotcom-gem/

Will verify copy with up a sample app tomorrow morning (German time).

Jd

raygao-gmail

unread,
Dec 1, 2011, 10:39:21 PM12/1/11
to activesa...@googlegroups.com
Hi,

I am trying to create a new record in the Database.Com with this GEM. I could not get it to work.

The schema is as follows.


The form creating the record is:
<%= form_for @participant, :url => { :action => "create" }, :html => {:class => "nifty_form"} do |form| %>
    <% Participant__c.attributes.select {|a| Participant__c.updateable?(a)}.each do |attr| %>
        <field>
            <%= form.label attr, Participant__c.label_for(attr) %>
            <% case Participant__c.field_type(attr) %>
                <% when "boolean" %>
                    <%= form.check_box attr %>
                <% when "multipicklist" %>
                <% when "picklist" %>
                    <% puts "Rendering picklist for #{attr}, value is #{@participant[attr]}, type is #{Participant__c.field_type(attr)}"%>
                    <%= form.select attr, Participant__c.picklist_values(attr).collect {|p| [p["label"], p["value"]]}, :multiple => (Participant__c.field_type(attr) == "multipicklist") %>
                <% else %>
                    <%= form.text_field attr%>
            <% end %>
        </field>
        <br>
    <% end %>
    <%= form.submit %>
<% end %>

This creates a page:

The code in the controller is:

  def create
    @participant = Participant__c.new(params[:participant__c])
    @alternative = Participant__c.coerce_params(params[:participant__c])

    respond_to do |format|
        @participant.reload
        format.html { redirect_to @participant, notice: 'Participant was successfully created.' }
        format.json { render json: @participant, status: :created, location: @participant }
      else
        format.html { render action: "new" }
        format.json { render json: @participant.errors, status: :unprocessable_entity }
      end
    end
  end


But, I am getting this error repeatedly.
Cannot deserialize instance of date from VALUE_STRING value  at [line:1, column:77]

I suspect that error is caused by the Date_of_Birth field (a Date type object).  How do I get around this error? Also, how to fix issues around a required custom field for an object?
Also, why are there double Owner ID text boxes?

Thanks a lot,

-Ray

Databasedotcom::SalesForceError in ParticipantsController#create

Cannot deserialize instance of date from VALUE_STRING value  at [line:1, column:77]

Rails.root: /Users/raygao2000/Desktop/12_recipes_book/recipe2/MyFitness

Application Trace | Framework Trace | Full Trace
app/controllers/participants_controller.rb:64:in `block in create'
app/controllers/participants_controller.rb:63:in `create'

Request

Parameters:

{"utf8"=>"✓",
 "authenticity_token"=>"E98bukMKc/K1mMTLbyBkzRjdWNIkPtsuuJWwujycfeI=",
 "participant__c"=>{"OwnerId"=>"005U0000000ZZGoIAO",
 "Owner"=>"005U0000000ZZGoIAO",
 "Email__c"=>"r...@jj.com",
 "Date_of_Birth__c"=>Thu,
 01 Dec 2011,
 "Gender__c"=>"male",
 "ProgramStartDate__c"=>Thu,
 01 Dec 2011,
 "ExpectedEndDate__c"=>Thu,
 01 Dec 2011,
 "Last_Name__c"=>"james",
 "First_Name__c"=>"pit"},
 "commit"=>"Create Participant  c"}

Show session dump

Show env dump

Response

Headers:


Mason Jones

unread,
Dec 1, 2011, 11:31:06 PM12/1/11
to activesa...@googlegroups.com
Hi. Without seeing the full source with line numbers it's a little hard to tell, but I believe the error you're getting is simply because whatever's being entered into the Date_of_Birth field isn't in a valid format that can be parsed into a Date. It doesn't appear to have anything to do with the databasedotcom gem, this is purely a Rails error.

Also, how to fix issues around a required custom field for an object?

What issues are you referring to exactly?

> Also, why are there double Owner ID text boxes?

I'm not sure about that one either. I'd recommend printing out the contents of Participant__c.attributes (either from the controller to the log or in your page) to verify that your form has the fields you'd expect, and then you can debug from there.


On Thu, Dec 1, 2011 at 7:39 PM, raygao-gmail <rayg...@gmail.com> wrote:
Hi,

I am trying to create a new record in the Database.Com with this GEM. I could not get it to work.

The schema is as follows.


The form creating the record is:
<%= form_for @participant, :url => { :action => "create" }, :html => {:class => "nifty_form"} do |form| %>
    <% Participant__c.attributes.select {|a| Participant__c.updateable?(a)}.each do |attr| %>
        <field>
            <%= form.label attr, Participant__c.label_for(attr) %>
            <% case Participant__c.field_type(attr) %>
                <% when "boolean" %>
                    <%= form.check_box attr %>
                <% when "multipicklist" %>
                <% when "picklist" %>
                    <% puts "Rendering picklist for #{attr}, value is #{@participant[attr]}, type is #{Participant__c.field_type(attr)}"%>
                    <%= form.select attr, Participant__c.picklist_values(attr).collect {|p| [p["label"], p["value"]]}, :multiple => (Participant__c.field_type(attr) == "multipicklist") %>
                <% else %>
                    <%= form.text_field attr%>
            <% end %>
        </field>
        <br>
    <% end %>
    <%= form.submit %>
<% end %>

This creates a page:

raygao-gmail

unread,
Dec 2, 2011, 12:01:24 AM12/2/11
to activesa...@googlegroups.com
1 The double Owner_ID is exhibited in the following Page source. I copied the original form code from the example
       <field>
            <label for="participant__c_OwnerId">Owner ID</label>
                    <input id="participant__c_OwnerId" name="participant__c[OwnerId]" size="30" type="text" />
        </field>
        <br>
        <field>
            <label for="participant__c_Owner">Owner ID</label>
                    <input id="participant__c_Owner" name="participant__c[Owner]" size="30" type="text" />
        </field>

2. The Save Error code comes back from Salesforce. The precise error is a Databasedotcom::SalesforceError  -> JSON_PARSER_ERROR
The Message Body is [{"message":"Cannot deserialize instance of date from VALUE_STRING value  at [line:1, column:106]","errorCode":"JSON_PARSER_ERROR"}]

How do I dig deeper? Has anyone tried to save records that contain other data types beside Text, i.e. numbers, dates, float, email, etc?

Thanks a lot for the quick response.

-Ray

Mason Jones

unread,
Dec 2, 2011, 1:03:50 AM12/2/11
to activesa...@googlegroups.com
It looks as though you have two attributes, OwnerId and Owner. For
some reason both are rendering with the label Owner ID, but they are
different fields.

I have records saving with various field types, including dates. If
the error is coming back from Salesforce, then I believe the issue is
that you are setting the property to a String, when it should be a
Date. Try converting the value in your Ruby code to Date and then
setting Participant__c.Date_of_Birth and I think you should be okay.
You can always try testing it with Time.now.to_date to verify that it
will accept a known-good date.

raygao-gmail

unread,
Dec 2, 2011, 11:53:48 AM12/2/11
to activesa...@googlegroups.com
OK, I got that huddle solved. But, I still have problems with update.

result = @participant.update_attributes(params[:participant__c])

results in errors. Net::HTTPBadRequest exception.

- even though, the JSON from debugger is:
{"Email__c":"la...@are4.us","Date_of_Birth__c":"1972-10-10","Gender__c":"male","ProgramStartDate__c":"1900-10-10","ExpectedEndDate__c":"1992-10-10","Last_Name__c":"james","First_Name__c":"lady"}

- path is:
http://xxxxxxxxxx -> /services/data/v23.0/sobjects/Participant__c/a05U0000000XGdvIAG
That looks perfectly correct to me.

What could be problem here? What is the correct way for updating a record from a web form?

best

-R


Mason Jones

unread,
Dec 2, 2011, 12:21:19 PM12/2/11
to activesa...@googlegroups.com
I've never seen that exception, so I'm not sure I can offer any advice
there. I have to say that I haven't tried the "update_attributes"
method -- I've always had to massage the data a bit before setting
things, so I've been simply doing a obj = Object.new(:attr1 =>
'hello', :attr2 => 'world') and then doing obj.save. If I were you I'd
try that and set only the bare minimum attributes (required fields) as
a test, to get to the smallest thing possible, and then build up from
there. I suppose it's possible that update_attributes is getting
confused and a bad value is sneaking in, though the debugger looks
okay. Do you have your client in "debugging: true" mode so that you
can see the details of the transaction in your log?

raygao-gmail

unread,
Dec 2, 2011, 7:18:42 PM12/2/11
to activesa...@googlegroups.com
Actually, even a straight resave failed and created an exception.

@participant = Participant__c.find(params[:id])
puts '--------started saving----------'
result = @participant.save

At this time, I have no clue how to fix this issue - updating an existing record.

-Ray

Mason Jones

unread,
Dec 2, 2011, 10:57:50 PM12/2/11
to activesa...@googlegroups.com
Do you have your client configured in debugging mode? Try that and
send over the results from the log. It should be pretty verbose so you
can see the full request and response. When I save a custom object,
for example, I see a response like this:

***** RESPONSE: Net::HTTPCreated ->
{"id":"a06K00000011SztIYW","errors":[],"success":true}

Or from a query (that didn't find anything):

***** RESPONSE: Net::HTTPOK -> {"totalSize":0,"done":true,"records":[]}

Try that and feel free to send over the output from the log. I'm not
sure I'll be able to help a lot but maybe one of the guys from
Salesforce may have some ideas.

raygao-gmail

unread,
Dec 3, 2011, 11:22:12 AM12/3/11
to activesa...@googlegroups.com
OK, the update() method definitely has a bug. According to the debugger, the @Request_has_body is true.  But, @Body is in fact nil.

This is a really serious problem. Basically, you can't update any records with the DatabaseDotCom Gem unless this bug is fixed.

It took me a while to step into all the code. But, this really needs to be fixed right way.

-R

Quinton Wall

unread,
Dec 3, 2011, 11:29:34 AM12/3/11
to activesa...@googlegroups.com, activesa...@googlegroups.com
I've pinged PM. Otherwise, it's all open source, it might be quicker to submit a pull request with a fix.

Q



On Dec 3, 2011, at 8:22, raygao-gmail <rayg...@gmail.com> wrote:

OK, the update() method definitely has a bug. According to the debugger, the @Request_has_body is true.  But, @Body is in fact nil.

This is a really serious problem. Basically, you can't update any records with the DatabaseDotCom Gem unless this bug is fixed.

It took me a while to step into all the code. But, this really needs to be fixed right way.

-R

<PastedGraphic-1.tiff>

Danny Burkes

unread,
Dec 3, 2011, 11:38:30 AM12/3/11
to activesa...@googlegroups.com
I hope to have time to look at this later this weekend.

- D

Mason Jones

unread,
Dec 3, 2011, 1:57:25 PM12/3/11
to activesa...@googlegroups.com
I'll take a look at this too, out of curiosity. I've been creating new
records, but I'm actually not positive whether I've updated any with
the latest version of the gem or not. I'll report back.

Mason Jones

unread,
Dec 3, 2011, 2:34:37 PM12/3/11
to activesa...@googlegroups.com
Hmm, I just did a test and updating a record worked fine. I just went
in with irb, and after authenticating I did the following:

> client.materialize("User")
> u = SFDC_Models::User.query("FirstName='Mason'")
> u[0].CompanyName = 'Test'
> u[0].save

It worked just fine, and I logged into SFDC and viewed the user to
verify that the update went through and the new CompanyName value was
there.

I'm using databasedotcom 1.2.5, if you want to double-check.

raygao-gmail

unread,
Dec 3, 2011, 3:17:37 PM12/3/11
to activesa...@googlegroups.com
I think I have figured out the problem. 

I have custom class Participant__c.  It has a custom field "Email__c", which is unique for each entry. 

When I tried to update the record, Email__c field is send back as well. As Email__c is unique, a previous record already existed in the system. Thus, it won't let me create another one. 

There is a slight issue with the exception handling logic of the gem. It is eating up Message Body from database.com response. It displays only "Net::HTTPBadRequest". The real message "HTTP code 400: duplicate value found: Email__c duplicates value on record with id: a05U0000000XKb8" got eaten up by the GEM.

That's why it is so confusing. 

I had to go back to my old gem to figure this out. In my old GEM, I had 
          raise Salesforce::Rest::AsfRequestError.new(message, http_code)
This shows the message body.

But, in the new gem, there is only:
raise SalesForceError.new(response) unless response.is_a?(expected_result_class || Net::HTTPSuccess)

This makes it very difficult to diagnose the real root cause of problems. 

I hope the Exception handling logic can be enhanced.

best,

-Ray

Raymond Gao

unread,
Dec 3, 2011, 4:25:52 PM12/3/11
to activesa...@googlegroups.com

Really hated to dwell on this issue. 


Anytimes, you have a field that is unique for a record, you cannot update it with the gem. Since, the GEM passes back the entire record (including the unique field), the system will block it.


Something really needs to be fixed. Otherwise, this is a pretty serious problems. A lot of apps will have unique field (secondary keys). And, you cannot update those field.


-R

Quinton Wall

unread,
Dec 3, 2011, 4:35:08 PM12/3/11
to activesa...@googlegroups.com, activesa...@googlegroups.com
Are you updating the unique value to something that exists already on another record?


raygao-gmail

unread,
Dec 3, 2011, 4:38:57 PM12/3/11
to activesa...@googlegroups.com
No, just the same record, which has the unique field. 

Apparently, the GEM constructs the request (PATCH) JSON with all the fields, including that unique field. And, the system on the other end blocks it.

It's not apparent, unless you dig really deep and monitor the generated JSON.

-R

Mason Jones

unread,
Dec 3, 2011, 4:57:11 PM12/3/11
to activesa...@googlegroups.com
I'm not entirely sure I follow, sorry if this seems obvious... Are you
saying that if you change the unique field, then the update doesn't
work? Or that if you have any unique field in the record, then you
can't update anything in that record?

I have certainly done updates to objects that have unique fields and
it has worked fine, so I just want to make sure I understand the
issue.

Thanks.

raygao-gmail

unread,
Dec 3, 2011, 5:03:06 PM12/3/11
to activesa...@googlegroups.com
The second, if you have an unique field in a record, your update will fail, even if you don't update that field. In my case, it was the email address that was unique.

-R

Danny Burkes

unread,
Dec 3, 2011, 5:04:42 PM12/3/11
to activesa...@googlegroups.com
When I tried to update the record, Email__c field is send back as well. As Email__c is unique, a previous record already existed in the system. Thus, it won't let me create another one. 


If you are trying to create another record with the same Email__c field, of course it's failing.

There is a slight issue with the exception handling logic of the gem. It is eating up Message Body from database.com response. It displays only "Net::HTTPBadRequest". The real message "HTTP code 400: duplicate value found: Email__c duplicates value on record with id: a05U0000000XKb8" got eaten up by the GEM.

That's why it is so confusing. 

I had to go back to my old gem to figure this out. In my old GEM, I had 
          raise Salesforce::Rest::AsfRequestError.new(message, http_code)
This shows the message body.

But, in the new gem, there is only:
raise SalesForceError.new(response) unless response.is_a?(expected_result_class || Net::HTTPSuccess)


As you can clearly see, the response isn't "eaten by the gem"- the entire response is included in the SalesForceError that is raised.  You can access the entire response with the #response method of the exception.  This is documented at http://rubydoc.info/github/heroku/databasedotcom/master/Databasedotcom/SalesForceError#response-instance_method
 
I hope the Exception handling logic can be enhanced.

In your opinion, what would improve it?

- D

Danny Burkes

unread,
Dec 3, 2011, 5:05:33 PM12/3/11
to activesa...@googlegroups.com
If indeed SFDC rejects an update on a unique field even when the primary key of the updated record matches the existing record containing that unique field, that's news to me.

- D

raygao-gmail

unread,
Dec 3, 2011, 5:12:07 PM12/3/11
to activesa...@googlegroups.com
In my case, I did not even provide an input box for Email__c. When you use update_attributes(params[:obj]), it automatically adds that field to the JSON request. Even a simple resave does that as well. You can play around with this in your DB.com and verify it.

The Exception Message Body should be logged out to the log file. Otherwise, you need to debug everything to see it. That is bit painful.

Just my 2 cents. ;-p

-R



Danny Burkes

unread,
Dec 3, 2011, 5:13:32 PM12/3/11
to activesa...@googlegroups.com
I just created a custom email field, with a uniqueness constraint, on a test instance of mine.  Loading that record, changing an unrelated field, and calling save on that record works fine.

Calling save does indeed send back all fields, but, SFDC does not reject the save because it realizes that the object that I am saving the same object that has the matching unique field.

Can you turn on debugging in your client (client.debugging = true), then send logs from the entire sequence of loading, updating, and saving that is causing you problems?

Thanks-

D

On Sat, Dec 3, 2011 at 2:03 PM, raygao-gmail <rayg...@gmail.com> wrote:

Danny Burkes

unread,
Dec 3, 2011, 5:14:28 PM12/3/11
to activesa...@googlegroups.com
Nothing is logged out to any log file unless you log it yourself.  

What "log file" are you suggested that it be logged to?

- D

Danny Burkes

unread,
Dec 3, 2011, 5:20:51 PM12/3/11
to activesa...@googlegroups.com
As Mason said, you have two attributes, OwnerId and Owner, that both have the label "Owner ID".  If you want them to have different labels, define them as such in your SFDC instance.

As for the Date updating issue, this is a known issue- see https://github.com/heroku/databasedotcom/issues/38

- D

raygao-gmail

unread,
Dec 3, 2011, 5:25:43 PM12/3/11
to activesa...@googlegroups.com
Here you go, the log, the controller and the _from file.

It's all here.

Thanks a lot. I really appreciate this.

development.log
participants_controller.rb
_form.html.erb

Danny Burkes

unread,
Dec 3, 2011, 5:30:13 PM12/3/11
to activesa...@googlegroups.com
I think you misunderstood me- I want you to turn on client debugging (client.debugging = true), which will log debugging information to stdout (using puts).  Capture stdout and send me the results- not your Rails log.

Thanks-

D

raygao-gmail

unread,
Dec 3, 2011, 5:35:25 PM12/3/11
to activesa...@googlegroups.com
log_out.rtf

Danny Burkes

unread,
Dec 3, 2011, 5:58:54 PM12/3/11
to activesa...@googlegroups.com
This seems extremely odd- you are logging in through login.salesforce.com, and it is telling you that your instance lives at https://momentum-custom-6841.database.com.  You then successfully find a Participant__c by id (a05U0000000XGdvIAG).  You then update some attributes in that object, and call save, which sends a PATCH to SFDC.

SFDC then replies with an HTML body- this is already weird.  Weirder still is that the HTML body contains the string "We are down for maintenance".

Has anyone seen the API reply with an HTML body before?  Joel, Alex, Quinton, etc- any insight you can give us?

For the full transcript, see https://gist.github.com/1428406

- D

On Sat, Dec 3, 2011 at 2:35 PM, raygao-gmail <rayg...@gmail.com> wrote:

--
You received this message because you are subscribed to the Google Groups "ActiveSalesforce" group.
To post to this group, send email to activesa...@googlegroups.com.
To unsubscribe from this group, send email to activesalesfor...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/activesalesforce?hl=en.



Thanks, -R

raygao-gmail

unread,
Dec 3, 2011, 8:15:54 PM12/3/11
to activesa...@googlegroups.com
Hey Danny,

Thanks for digging through this. 

Here is what I did.

1. I debugged the GEM. and got the following JSON.
serialized_json = '{"Date_of_Birth__c":"1985-4-9","Gender__c":"male","ProgramStartDate__c":"1972-10-10","ExpectedEndDate__c":"1999-10-15","Last_Name__c":"james","First_Name__c":"pit"}'

2. I plug that JSON in my old REST GEM and did a straight update. And, it worked.
"********************************************************************************"
"Set up code"
binding user id is: 005U0000000ZZGoIAO
oauth token is: 00DU0000000JvPW!AQgAQGjEQTXRDw.iRoa6JOzeVkPY1ede48AM1bSleilsAPd_yX4C18vN41V6pf21joMTCIMiV4IAS3pLQJC91C7qdM23YTYd
2171446220 Raymond Gao
New Object created: id -> a05U0000000XGdvIAG
--update that account with json--
/Library/Ruby/Gems/1.8/gems/httparty-0.7.8/lib/httparty/response.rb:77: warning: Object#id will be deprecated; use Object#object_id
warning: peer certificate won't be verified in this SSL session

Finished in 4.229 seconds.

3. That works fine.

4. It's just with Database.com, I can't get it to work regardless the situation, whether I used update_attributes(), save(). Somehow, the PATCH is not getting it. It appears that with my old gem, it hits against rest_svr: https://na12.salesforce.com    But, with the new gem, it is going against    https://momentum-custom-6841.database.com/services/data/v23.0

And, that's a show stopper.  So, my theory is that there has been some changes made to the load-balancers or proxy-servers, the redirection might be causing issues with PATCH verb.

Can someone verify, momentum-servers are accepting PATCH commands.

best,

-R

Joel Dietz

unread,
Dec 13, 2011, 5:43:16 AM12/13/11
to activesa...@googlegroups.com
Was not paying attention to this thread -- but I suspect that unusual provisions apply when the servers are in maintenance mode. Of course they shouldn't respond with an HTML body, but it does not surprise me that they do.

That said, I don't think this weirdness substantially effects anything on this thread, since I assume the "maintenance mode" was limited to a couple hour time span when the REST API was unavailable. 

Jd
Reply all
Reply to author
Forward
0 new messages