find_by_sql and xml_serializer problems

Hi, I'm doing a find_by_sql and am getting an odd error when trying to render the result to xml.

The find is: children_list = find_by_sql("SELECT components.componentid, components.logicalname, versions.level, versions.branch, versions.sequence FROM components, versions where components.componentid = '" + component_id + "'" + " AND versions.componentid = '" + component_id + "'")

When I do a render :xml I get this: /var/lib/gems/1.8/gems/activerecord-2.1.0/lib/active_record/ serializers/xml_serializer.rb:308: warning: Object#type is deprecated; use Object#class

Also the xml out put I get sorta looks like this: <components type="array">     <component>         <branch type="NilClass">0</branch>         <componentid type="integer">342</componentid>         <level type="NilClass">0</level>         <logicalname>SETUP </logicalname>         <sequence type="NilClass">0</sequence>     </component> ... </components>

Anyone know what that error/warning is? And also, why are all the NilClass's there in the XML output?

I think you should have some model name.find_by_sql. eg: If the name of your model is User then you can use User.find_by_sql("SELECT components.componentid, components.logicalname, versions.level, versions.branch, versions.sequence FROM components, versions where components.componentid = ' #{component_id}' AND versions.componentid = '#{component_id}' ")

I didn't think that would matter as the find was already inside the model. In this case a model called Component. So it would have been Component.find_by_sql. Tried it in any case and it didn't make a difference. On the other hand, if I called the find with the other model (in this case called Version) inside the Component model i.e. inside the Component model @somelist = Version.find_by_sql(blah blah) had an interesting result... The error/warning message was the same but the resulting XML wasn't.

When I did the @somelist = find_by_sql or @somelist = Component.find_by_sql (both inside the Component model) had the xml result from my first post.

But when I did @somelist = Version.find_by_sql(blah blah) inside the Component model the xml result was

<versions type="array">     <version>         <branch type="integer">0</branch>         <componentid type="integer">342</componentid>         <level type="integer">0</level>         <logicalname type="NilClass">SETUP </

        <sequence type="integer">0</sequence>     </version> ... </versions>

The <versions> and <version> tags are understandable but the interesting thing is the NilClass for all the elements retrieved from the components table.

Bump: Anyone have any ideas?

Activerecord uses the column attributes for the table in order to workout what the types should be. However if you do a find by sql which joins other tables activerecord doesn't know what the types are for the columns from other tables. The warning you got is because of the same thing: line 308 of the file is @record.class.columns_hash[name].type

but @record.class.columns_hash[name] will be nil if name does not correspond to a column from that table. (and so the type that is computed is NilClass). You could sidestep this by using :include to include the serialization of the version object (although this would result in slightly different xml) or possibly by playing around with the :methods options or by telling AR to just not put the types in the xml (the :skip_types option)

Fred

Thanks for the reply. Sorry for taking a while to respond back. It was a national holiday on our side so wasn't around during the weekend.

Anyhow, hmm...As you suggested, I used the skip_types option as I don't need the types. Obviously I still get the 308 warning which is really annoying. I will have to look into the :include option again as the last time I tried it using find() I didn't have much luck for some odd reason. I know nothing about the :method option so will need to look into that one. You mentions "@record.class.columns_hash[name] will be nil if name does not correspond to a column from that table". What I don't understand is why wouldn't it correspond to the columns from the table? I mean, if they didn't correspond to the column for that table, the find_by_sql query would fail no? Or are you saying that because 'name' is something along the lines of "versions.componentid" instead of "componentid" it gets messed up by the table name ("versions")? Or have I gone totally off tangent here? In any case, thanks for all the help, greatly appreciated.

Thanks for the reply. Sorry for taking a while to respond back. It was a national holiday on our side so wasn't around during the weekend.

Anyhow, hmm...As you suggested, I used the skip_types option as I don't need the types. Obviously I still get the 308 warning which is really annoying. I will have to look into the :include option again as the last time I tried it using find() I didn't have much luck for some odd reason. I know nothing about the :method option so will need to look into that one. You mentions "@record.class.columns_hash[name] will be nil if name does not correspond to a column from that table". What I don't understand is why wouldn't it correspond to the columns from the table? I mean, if they didn't correspond to the column for that table, the find_by_sql query would fail no? Or are you saying that because

Rails is doing record.class.columns_hash ie it's looking at the
columns hash for one class in particular (in this case Component)
which quite naturally knows nothing about the columns on the versions
table.

Fred

Thanks for the reply. Sorry for taking a while to respond back. It was a national holiday on our side so wasn't around during the weekend.

Anyhow, hmm...As you suggested, I used the skip_types option as I don't need the types. Obviously I still get the 308 warning which is really annoying. I will have to look into the :include option again as the last time I tried it using find() I didn't have much luck for some odd reason. I know nothing about the :method option so will need to look into that one. You mentions "@record.class.columns_hash[name] will be nil if name does not correspond to a column from that table". What I don't understand is why wouldn't it correspond to the columns from the table? I mean, if they didn't correspond to the column for that table, the find_by_sql query would fail no? Or are you saying that because

Rails is doing record.class.columns_hash ie it's looking at the
columns hash for one class in particular (in this case Component)
which quite naturally knows nothing about the

Hmm...strange. Well, not really strange as I understand what you are saying but it's strange that there is no full support. I would think that I am not the only one that would want to search from multiple tables...

cinderedmonkey wrote:

Hmm...strange. Well, not really strange as I understand what you are saying but it's strange that there is no full support. I would think that I am not the only one that would want to search from multiple tables...

On Sep 4, 3:31�am, Frederick Cheung <frederick.che...@gmail.com>

Hi, did you ever find a solution for this as I'm having exactly the same problem as you describe here? Since the xml I'm producing is public I cannot really change it and since I don't need the type (I use the :skip_types option) I cannot understand why the code producing this warning haven't been modified yet. I'm running rails 2.2.2. Well, any input would be great.

Magnus Holmlund wrote:

cinderedmonkey wrote:

Hmm...strange. Well, not really strange as I understand what you are saying but it's strange that there is no full support. I would think that I am not the only one that would want to search from multiple tables...

On Sep 4, 3:31�am, Frederick Cheung <frederick.che...@gmail.com>

Hi, did you ever find a solution for this as I'm having exactly the same problem as you describe here? Since the xml I'm producing is public I cannot really change it and since I don't need the type (I use the :skip_types option) I cannot understand why the code producing this warning haven't been modified yet. I'm running rails 2.2.2. Well, any input would be great.

Additional information: As for now I'm running this patch to avoid the problem. Not very nice but it works. Feel free to comment.

#Removes a warning informing about type is deprecated #/var/lib/gems/1.8/gems/activerecord-2.1.0/lib/active_record/serializers/xml_serializer.rb:308: warning: Object#type is deprecated;use Object#class #See http://rails.lighthouseapp.com/projects/8994/tickets/732-deprecation-warning-in-xml_serializer-rb-308 #and Find_by_sql and xml_serializer problems - Rails - Ruby-Forum module ActiveRecord #:nodoc:   class XmlSerializer < ActiveRecord::Serialization::Serializer #:nodoc:     class Attribute #:nodoc:       def compute_type           type = @record.class.serialized_attributes.has_key?(name) ? :yaml : (@record.class.columns_hash[name].nil? ? nil.class : @record.class.columns_hash[name].type)

          case type             when :text               :string             when :time               :datetime             else               type           end         end     end   end end