As I plod on in my journey to grasp Rails (and Ruby) I'm often surprised by the difficulty in figuring out how to do something. Most of the time the surprise is a pleasant one, in that it's much easier than I expected. But then sometimes something that I expect to be easy leaves me scratching my head.
Today I am trying to retrieve XML data from a remote server, parse that data into a class, then save it to the database.
I "knew" the XML part would be hard and the saving easy.
Well, retrieving and parsing the data took maybe five minutes to get working, instead of all day like I expected
But now I can't properly save it.
The columns always end up filled with nulls. To simply the problem I eliminated the retrieval part and tried to just create and save, like this:
#in the account_application controller
account_application = AccountApplication.new
account_application.first_name = "George"
account_application.save
A row gets created, but first_name is null.
In the model file I have
class AccountApplication < ActiveRecord::Base
attr_writer :first_name
Surely I'm doing something that's just plain wrong, but I am stumped.
Thanks,
-George
#in the account_application controller
account_application = AccountApplication.new
account_application.first_name = "George"
account_application.save
A row gets created, but first_name is null.
In the model file I have
class AccountApplication < ActiveRecord::Base
attr_writer :first_name
Get rid of this attr_writer line and any others that match the columns in your account_applications table...
-philip
Thanks. I guess those are already done for me. That changes my question
I’d put that in trying to solve a different problem in get the data out of the REXML document. In my rhtml file I have
<% @doc.elements.each(“application_list/application”) { |element| %>
<%= element.elements[“first_name”] %>
<% } %>
I get what I expect, the applicant’s first name. But if (back in the controller) I try to assign it:
account_application.first_name = element.elements[“first_name”]
I get a first_name of — &id001 !ruby/object:REXML::Element
So unlike I thought, I now see I don’t grasp how to extract the data from the document.
I appreciate the list’s patience while I try to sort out what must be some pretty fundamental things.
-George
account_application.first_name = element.elements["first_name"]
I get a first_name of --- &id001 !ruby/object:REXML::Element
So unlike I thought, I now see I don't grasp how to extract the data
from the document.
I haven't used REXML, but that string looks like the string version of a ruby object... so you haven't gone far enough... you'll need something like:
element.elements["first_name"].value
or something to retrieve the actual value of that element, not the object itself. CHeck REXML's docs for what "value" should actually be.
Thanks Phillip.
Yes, I figured I was in the wrong “place” in the tree, but then I don’t understand what magic allows this to work:
<% @doc.elements.each(“application_list/application”) { |element| %>
<%= element.elements[“first_name”] %>
<% } %>
With that in the .rhtml file I get a list of the first names. So I don’t get how that code knows how to extract the text, but when I try to assign from it I get the object string instead.
I’ve tried several things, obviously without success. For instance, using get_text:
account_application.first_name = app_data.elements[“first_name”].get_text
yields: — !ruby/object:REXML::Text
This is a bit frustrating. I know exactly what I want to do, but I just don’t know how to explain it to Ruby.
-George
Thanks Phillip.
Yes, I figured I was in the wrong "place" in the tree, but then I
don't understand what magic allows this to work:
<% @doc.elements.each("application_list/application") { |element| %>
<%= element.elements["first_name"] %><BR>
<% } %>
With that in the .rhtml file I get a list of the first names. So I
don't get how that code knows how to extract the text, but when I try
to assign from it I get the object string instead.
I've tried several things, obviously without success. For instance,
using get_text:
account_application.first_name = app_data.elements
["first_name"].get_text
yields: --- !ruby/object:REXML::Text
This is a bit frustrating. I know exactly what I want to do, but I
just don't know how to explain it to Ruby.
What about trying ".to_s" ? I think the <%= perhaps does the implicitly perhaps...
Well, that explained a few things. INstead of just the name that gives
<first_name>George</first_name>
And viewing the source of the web page produced by the rhtml file reveals that that is what’s in there. I hadn’t realized it, of course, because the “unknown tags” get ignored, and so I saw only the name.
It seems like I’m still one level too high, but I can’t see any way to go any deeper. I’ve tried a dozen different things.
Is it possible that the XML I’m receiving is malformed, and REXML is considering that whole thing to be the data?
I guess I’m biting off too much at once, having done little before with XML, Ruby, or Rails.
It sure seems like I’m close, though, and I’ve managed to already get so much working in Rails that I thought I could iron out all the small wrinkles.
Thanks for your help, Phillip. I appreciate it. I’ve got some more digging to do.
-George
I've tried several things, obviously without success. For instance,
using get_text:
account_application.first_name = app_data.elements
["first_name"].get_text
yields: --- !ruby/object:REXML::Text
This is a bit frustrating. I know exactly what I want to do, but I
just don't know how to explain it to Ruby.
Success.
For completeness, here's the working version:
@doc.elements.each("application_list/application") { |app_data|
account_application = AccountApplication.new
account_application.first_name = app_data.elements["first_name"].text #.text was the missing ingredient
....
account_application.save
}
Seems obvious now.
I'm sure that I had already tried text, but I guess something else had been wrong and I made two changes at once.
(Phillip , thanks for your help)
-George