This could have been solved earlier. But I couldn''t find a solution. Lets say I have an abstract base model called ''Question'' and sub- models like Mcq, TrueFalse and FillInTheBlank. Mcq and TrueFalse models have a has_many relation with another model named ''Choice'' whereas FillInTheBlank model doesn''t have this. So I have defined the choice relation in Mcq and TrueFalse class. While instantiating the Mcq and TrueFalse classes in my controllers I don''t know which class the instance is going to belong (all I know is it doesn''t belong to FillInTheBlank). So I call it like ''Question.find(params[:id])''. Due to the ''type'' column I get either an ''Mcq'' instance or a ''TrueFalse'' instance. Perfect. But the code breaks down when I call choices method on this new instance. It says "NoMethodError: undefined method `choices'' for #<Mcq:0x3046a84>" However this problem doesn''t come up if I call the find method on the correct class i.e. Mcq.find() directly. But as I said earlier the problem is I don''t know whether the question is going to be a Mcq or a TrueFalse. One dirty solution I tried is to call find on the abstract class (Question.find()), get value of ''type'' attribute and issue another find statement on the correct class (Mcq.find()). But even that didn''t solve the problem. Has anybody faced this kind of a problem? Can someone point me in the right direction? Thanks much. subbu --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Looks like I have found one solution. I had 2 definitions for the classes Mcq and TrueFalse, one in separate files named mcq.rb and true_false.rb and another definition in the file question.rb (the abstract class itself). I had to have these definitions in 2 files because otherwise I couldn''t call the concrete classes directly without first loading the abstract class. But that apart, my has_many relation was not in the abstract class file. So it was not getting loaded when I issued the find statement on the abstract class. But if I issue the find on the concrete class directly (without calling the abstract class before) it would''ve loaded the has_many by then and would load the relations properly. Bit tricky. To be on the safer side now I have moved all my definitions to the abstract class file and keeping the concrete class files empty. -subbu On Sep 9, 10:45 pm, Subbu <subramani.athiku...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> This could have been solved earlier. But I couldn''t find a solution. > > Lets say I have an abstract base model called ''Question'' and sub- > models like Mcq, TrueFalse and FillInTheBlank. Mcq and TrueFalse > models have a has_many relation with another model named ''Choice'' > whereas FillInTheBlank model doesn''t have this. So I have defined the > choice relation in Mcq and TrueFalse class. While instantiating the > Mcq and TrueFalse classes in my controllers I don''t know which class > the instance is going to belong (all I know is it doesn''t belong to > FillInTheBlank). So I call it like ''Question.find(params[:id])''. Due > to the ''type'' column I get either an ''Mcq'' instance or a ''TrueFalse'' > instance. Perfect. But the code breaks down when I call choices method > on this new instance. It says "NoMethodError: undefined method > `choices'' for #<Mcq:0x3046a84>" > > However this problem doesn''t come up if I call the find method on the > correct class i.e. Mcq.find() directly. But as I said earlier the > problem is I don''t know whether the question is going to be a Mcq or a > TrueFalse. > > One dirty solution I tried is to call find on the abstract class > (Question.find()), get value of ''type'' attribute and issue another > find statement on the correct class (Mcq.find()). But even that didn''t > solve the problem. > > Has anybody faced this kind of a problem? Can someone point me in the > right direction? > > Thanks much. > subbu--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
the fact that you had 2 definitions each for your concretes looks to be your issue.. in order to do this and behave well under rails you will need exactly 3 files and 3 classes.. I am willing to bet that one of your implementations had the choices() method implemented and the other didn''t.. app/models/choice.rb class Choice < ActiveRecord::Base abstract true # no need to implement choices here unless you have a default implementation end app/models/mcq.rb class Mcq < Choice def choices end end app/models/true_false.rb class TrueFalse < Choice def choices end end hth ilan Subbu wrote:> Looks like I have found one solution. > > I had 2 definitions for the classes Mcq and TrueFalse, one in separate > files named mcq.rb and true_false.rb and another definition in the > file question.rb (the abstract class itself). I had to have these > definitions in 2 files because otherwise I couldn''t call the concrete > classes directly without first loading the abstract class. But that > apart, my has_many relation was not in the abstract class file. So it > was not getting loaded when I issued the find statement on the > abstract class. But if I issue the find on the concrete class directly > (without calling the abstract class before) it would''ve loaded the > has_many by then and would load the relations properly. Bit tricky. To > be on the safer side now I have moved all my definitions to the > abstract class file and keeping the concrete class files empty. > > -subbu-- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Ilan, Mcq and TrueFalse descend from question and not choice. The correct structure is below. app/models/choice.rb class Question < ActiveRecord::Base end app/models/question.rb class Question < ActiveRecord::Base self.abstract_class = true end class Mcq < Question;end class TrueFalse < Question;end app/models/mcq.rb class Mcq < Question has_many choices end app/models/true_false.rb class TrueFalse < Question has_many choices end As you can see my question.rb had definitions for all the classes, one abstract and 2 concrete but they didn''t have the has_many relation to choices. This relation was present in a different file which was not loaded at the time of calling the method. That was causing the issue. -subbu On Sep 10, 2:08 am, Ilan Berci <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> the fact that you had 2 definitions each for your concretes looks to be > your issue.. in order to do this and behave well under rails you will > need exactly 3 files and 3 classes.. > > I am willing to bet that one of your implementations had the choices() > method implemented and the other didn''t.. > > app/models/choice.rb > class Choice < ActiveRecord::Base > abstract true > # no need to implement choices here unless you have a default > implementation > end > > app/models/mcq.rb > class Mcq < Choice > def choices > end > end > > app/models/true_false.rb > class TrueFalse < Choice > def choices > end > end > > hth > > ilan > > > > Subbu wrote: > > Looks like I have found one solution. > > > I had 2 definitions for the classes Mcq and TrueFalse, one in separate > > files named mcq.rb and true_false.rb and another definition in the > > file question.rb (the abstract class itself). I had to have these > > definitions in 2 files because otherwise I couldn''t call the concrete > > classes directly without first loading the abstract class. But that > > apart, my has_many relation was not in the abstract class file. So it > > was not getting loaded when I issued the find statement on the > > abstract class. But if I issue the find on the concrete class directly > > (without calling the abstract class before) it would''ve loaded the > > has_many by then and would load the relations properly. Bit tricky. To > > be on the safer side now I have moved all my definitions to the > > abstract class file and keeping the concrete class files empty. > > > -subbu > > -- > Posted viahttp://www.ruby-forum.com/.--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---