Hi, I''ve started working on a CMS in Ruby on Rails and have been thinking of implenting a kind of EAV datamodel (http://ycmi.med.yale.edu/nadkarni/eav_cr_contents.htm). In short each content object is of class ContentNode and each field in the contentNode is implementen by associations. So for a poll you have a question field stored in a StringNode table. For each option for the poll you have a answer field stored in a StringNode table and a count field stored in a IntNode table. So far i have the following models: class ContentNode < ActiveRecord::Base belongs_to :parent, "ContentNode", :foreign_key => "parent_id" end class StringNode < ActiveRecord::Base belongs_to :content_node end class IntNode < ActiveRecord::Base belongs_to :content_node end class Poll < ContentNode has_one :question_field,:class_name => "StringNode",:foreign_key => "content_node_id", :conditions => "name = ''question''", :dependent => :destroy has_many :options, :class_name => "Option", :foreign_key => "parent_id" def question question_field.nil? ? nil : question_field.value end def question=(x) if question_field.nil? then create_question_field( { "name" => "question" } ) end question_field.value=x end def votes count=0 for option in options count += options.count end return count end end class Option < ContentNode has_one :answer_field, :class_name => "StringNode", :foreign_key => "content_node_id", '' :conditions => "name = ''answer''", :dependent => :destroy has_one :count_field, :class_name => "IntNode", :foreign_key => "content_node_id", :conditions => "name = ''count''", :dependent => :destroy def answer answer_field.nil? ? nil : answer_field.value end def answer=(x) if answer_field.nil? then create_answer_field( { "name" => "answer" } ) end answer_field.value=x end def count if count_field.nil? then create_count_field( { "name" => "count", "value" => "0" } ) end end def count=(x) if count_field.nil? then create_count_field( { "name" => "count", "value" => "0" } ) end count_field.value=x end end Whit this datamodel I can do the following: @poll = Poll.new @poll.question = "Does this thing work?" @option = Option.new @option.answer = "Yes" @poll.options << @option @option = Option.new @option.answer = "No" @poll.option << @topion @poll.save What i would like to do is to extend the ActiveRecord class so I can do the following: @poll = Poll.new( { "question" => "Does this thing work?" } ) I''m kinda new to Ruby (and Rails), but i guess I have to override the ActiveRecord::Base::columns() function and inject my own "custom" fields (question) ? mvh Jan Åge Johnsen Hålogaland IKT-Senter AS Rødbergveien 14 N-9480 Harstad Norway Tel.: +47 77 04 26 56 Fax.: +47 77 04 25 99 -- This message has been scanned for viruses and dangerous content by The MailScanner at Halogaland IKT Senter, www.hikt.no, and is believed to be clean. _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Hi, I''m working on nearly exactly the same (although I didn''t know that there''s an "official" name - EAV/CR - for it ). I''ve already wondered why this didn''t come up earlier on this list, as this is so damn useful. I didn''t think about extending Rails for this task, yet. I just planned to add methods to the "Entity"-model for populating the "virtual" attributes, but having it in ActiveRecord would be much more cool: Something like "acts_as_eav" would lead to a _real_ object/relational mapping with the ability to store objects of very different kind without altering the database schema. But I fear that it isn''t done by just overwriting 1 oder 2 methods... Max PS: Sorry, this didn''t answer your question - but maybe it inspired one of those people who have more competence in writing acts_as_-generators than I have ;-)> Hi, > > I''ve started working on a CMS in Ruby on Rails and have been thinking > of implenting a kind of EAV datamodel > (http://ycmi.med.yale.edu/nadkarni/eav_cr_contents.htm). > In short each content object is of class ContentNode and each field in > the contentNode is implementen by associations. > > So for a poll you have a question field stored in a StringNode table. > For each option for the poll you have a answer field stored in a > StringNode table and a count field stored in a IntNode table. > > So far i have the following models: > > *class* ContentNode < ActiveRecord::Base > belongs_to :parent, "ContentNode", :foreign_key => "parent_id" > *end* > > class StringNode < ActiveRecord::Base > belongs_to :content_node > end > > class IntNode < ActiveRecord::Base > belongs_to :content_node > end > > class Poll < ContentNode > has_one :question_field,:class_name => > "StringNode",:foreign_key => "content_node_id", > :conditions => "name = ''question''", :dependent => > :destroy > has_many :options, :class_name => "Option", :foreign_key => > "parent_id" > > def question > question_field.nil? ? nil : question_field.value > > end > > def question=(x) > if question_field.nil? then > create_question_field( { "name" => > "question" } ) > end > question_field.value=x > end > > def votes > count=0 > for option in options > count += options.count > end > return count > end > end > > class Option < ContentNode > has_one :answer_field, :class_name => "StringNode", > :foreign_key => "content_node_id", '' > :conditions => "name = ''answer''", :dependent => :destroy > has_one :count_field, :class_name => "IntNode", > :foreign_key => "content_node_id", > :conditions => "name = ''count''", :dependent => :destroy > > def answer > answer_field.nil? ? nil : answer_field.value > > end > > def answer=(x) > if answer_field.nil? then > create_answer_field( { "name" => "answer" } ) > end > > answer_field.value=x > end > > def count > if count_field.nil? then > create_count_field( { "name" => "count", > "value" => "0" } ) > end > end > > def count=(x) > if count_field.nil? then > create_count_field( { "name" => "count", > "value" => "0" } ) > end > count_field.value=x > end > end > > *Whit this datamodel I can do the following:* > @poll = Poll.new > @poll.question = "Does this thing work?" > @option = Option.new > @option.answer = "Yes" > @poll.options << @option > @option = Option.new > @option.answer = "No" > @poll.option << @topion > @poll.save > > *What i would like to do is to extend the ActiveRecord class so I can > do the following:* > *@poll = Poll.new( { "question" => "Does this thing work?" } )* > > *I''m kinda new to Ruby (and Rails), but i guess I have to override the > ActiveRecord::Base::columns() function and inject my own "custom" > fields (question) ?*
Hi, Nice to see that I''m not the only one with this "crazy" idea ;) You might be right about it not being as easy as overwriting 1 or 2 methods, but I think you can get some basic functions to work rather easily. I was planning to add a "has_one_eav_field" module that would automatically generate the relation and get/set code: Example: class Poll < ContentNode has_one_eav_field :question, :class_name => "StringNode", :foreign_key => "content_node_id", :default_value => "Something" end That would generate the following class Poll < ContentNode has_one :question_field,:class_name => "StringNode",:foreign_key => "content_node_id", :conditions => "name = ''question''", :dependent => :destroy def question # Returns default value if set question_field.nil? "Something" : question_field.value end def question=(x) if question_field.nil? then create_question_field( { "name" =>"question" } ) end question_field.value=x end end I haven''t had much time to look at the ActiveRecord source (and I don''t know ruby that well), but I think that if I can extend this I can get it to use my generated setters and getters to retrive/store data for the fields. Another problem however with my current approach is that if a Poll object is created and question field set, but the poll objected is not saved the StringNode still gets created in the database. So I think I need to hook into the Poll object when it?s destroyed (from memory) and delete all EAV fields if Poll.id does not exists. mvh Jan Åge Johnsen Hålogaland IKT-Senter AS Rødbergveien 14 N-9480 Harstad Norway Tel.: +47 77 04 26 56 Fax.: +47 77 04 25 99 Maximilian Schöfmann <Maximilian.Schoefmann-3GotyFbwtrfaSurJjR/IPg@public.gmane.org> Sent by: rails-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org 03.11.2005 11:38 Please respond to rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org To rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org cc Subject Re: [Rails] Adding custom columns to ActiveRecord Hi, I''m working on nearly exactly the same (although I didn''t know that there''s an "official" name - EAV/CR - for it ). I''ve already wondered why this didn''t come up earlier on this list, as this is so damn useful. I didn''t think about extending Rails for this task, yet. I just planned to add methods to the "Entity"-model for populating the "virtual" attributes, but having it in ActiveRecord would be much more cool: Something like "acts_as_eav" would lead to a _real_ object/relational mapping with the ability to store objects of very different kind without altering the database schema. But I fear that it isn''t done by just overwriting 1 oder 2 methods... Max PS: Sorry, this didn''t answer your question - but maybe it inspired one of those people who have more competence in writing acts_as_-generators than I have ;-)> Hi, > > I''ve started working on a CMS in Ruby on Rails and have been thinking > of implenting a kind of EAV datamodel > (http://ycmi.med.yale.edu/nadkarni/eav_cr_contents.htm). > In short each content object is of class ContentNode and each field in > the contentNode is implementen by associations. > > So for a poll you have a question field stored in a StringNode table. > For each option for the poll you have a answer field stored in a > StringNode table and a count field stored in a IntNode table. > > So far i have the following models: > > *class* ContentNode < ActiveRecord::Base > belongs_to :parent, "ContentNode", :foreign_key => "parent_id" > *end* > > class StringNode < ActiveRecord::Base > belongs_to :content_node > end > > class IntNode < ActiveRecord::Base > belongs_to :content_node > end > > class Poll < ContentNode > has_one :question_field,:class_name => > "StringNode",:foreign_key => "content_node_id", > :conditions => "name = ''question''", :dependent => > :destroy > has_many :options, :class_name => "Option", :foreign_key => > "parent_id" > > def question > question_field.nil? ? nil : question_field.value > > end > > def question=(x) > if question_field.nil? then > create_question_field( { "name" => > "question" } ) > end > question_field.value=x > end > > def votes > count=0 > for option in options > count += options.count > end > return count > end > end > > class Option < ContentNode > has_one :answer_field, :class_name => "StringNode", > :foreign_key => "content_node_id", '' > :conditions => "name = ''answer''", :dependent => :destroy > has_one :count_field, :class_name => "IntNode", > :foreign_key => "content_node_id", > :conditions => "name = ''count''", :dependent => :destroy > > def answer > answer_field.nil? ? nil : answer_field.value > > end > > def answer=(x) > if answer_field.nil? then > create_answer_field( { "name" => "answer" })> end > > answer_field.value=x > end > > def count > if count_field.nil? then > create_count_field( { "name" => "count", > "value" => "0" } ) > end > end > > def count=(x) > if count_field.nil? then > create_count_field( { "name" => "count", > "value" => "0" } ) > end > count_field.value=x > end > end > > *Whit this datamodel I can do the following:* > @poll = Poll.new > @poll.question = "Does this thing work?" > @option = Option.new > @option.answer = "Yes" > @poll.options << @option > @option = Option.new > @option.answer = "No" > @poll.option << @topion > @poll.save > > *What i would like to do is to extend the ActiveRecord class so I can > do the following:* > *@poll = Poll.new( { "question" => "Does this thing work?" } )* > > *I''m kinda new to Ruby (and Rails), but i guess I have to override the > ActiveRecord::Base::columns() function and inject my own "custom" > fields (question) ?*_______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails -- This message has been scanned for viruses and dangerous content by The MailScanner at Halogaland IKT Senter, www.hikt.no, and is believed to be clean. -- This message has been scanned for viruses and dangerous content by The MailScanner at Halogaland IKT Senter, www.hikt.no, and is believed to be clean. _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails