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