views:

29

answers:

1

I am trying to create a Single Table Inheritance.

However, the Controller must be able to know which class to find or create. These are based on another class.

For example, ContactEvent with type = Letter needs to grab attributes from a corresponding Model called Letter.

Here's what I've tried to do and hit a snag, labelled below.

I need to be able to dynamically call assign a value of EventClass so that it can be Letter.find(:conditions =>) or Calls.find(:conditions =>) depending on which type the controller is acting on.

  def new
    @contact_event = ContactEvent.new
    @contact_event.type = params[:event_type] # can be letter, call, postcard, email
    @contact_event.event_id = params[:event_id] # that ID to the corresponding Model
    @contact_event.contact_id = params[:contact]

    @EventClass = case
      when @contact_event.type == 'letter' then 'Letter'
      when @contact_event.type == 'call' then 'Call'
      when @contact_event.type == 'email' then 'Email'

SNAG BELOW:

    @event = @EventClass.find(@contact_letter.letter_id) #how do I make @EventClass actually the Class?SNAG

    # substitution of variables into the body of the contact_event
    @event.body.gsub!("{FirstName}", @contact.first_name)
    @event.body.gsub!("{Company}", @contact.company_name) 
    @evebt.body.gsub!("{Colleagues}", @colleagues.to_sentence)

    @contact_event.body = @event.body
    @contact_event.status = "sent"

  end
+2  A: 
@event_class = case @contact_event.type
  when 'letter' then Letter
  when 'email'  then Email
  when 'call'   then Call
end

You have to assign the class itself, not a string. You can then just call @event_class.find(whatever). Some things to note:

Single table inheritance is supported, and handled automatically by Rails. You can have Letter, Email and Call inherit from ContactEvent. Read more at Rails API (section Single Table Inheritance)

You can convert your string directly by calling @contact_event_type.classify.constantize (this turns "call" into Call, for example).

Also, try to name your variables according to ruby conventions (@event_type instead of @EventType), and check your use of the case statement.

Hope it's useful :)

Chubas
Hi, thanks, I did read the Single Table INheritance an dit is supported...but I thought only if you call out the sub-classes specifically....but seems like I still need to identify what that is....? Or can I use .class method and pass it thorugh? Is there a way for me to *not* have to you the :type variable passed through?
Angela
I'm not sure I understand what your schema is. Are email, call and letter subtypes of ContactEvent (which seems the more logical to me)?If so, I think you cannot escape passing the parameter (or call different URLs), and in your controller you'd just call `@event_class.new`, since the @even_class variable holds the class itself (remember, in Ruby, classes are objects **too**)
Chubas
Actual, ContactEmail, ContactCall and ContactLetter at the subtype of ContactEvent.A ContactEmail however, is instantiated with Email.id of whatever instance of Email is passed into it. Think of Email as a template, and ContactEmail is the execution of Email with a specific Contact.
Angela