views:

40

answers:

2

I have a number of activities that have a calculated scheduled date. The activities, for example, Email, have a email.days method which is the days from a Contact.start_date on which it should be sent.

This means contact.start_date + email.days yields a date on which email is sent to contact.

I would like to use link_to around the date, so I can see all the emails and associated contacts that are to be scheduled on that date.

However, this "date" is not an attribute or an associate, so I'm not linking to a model's view. It's calculated.

So:

1) What should the actual "format" of the date that gets passed in the URl be? What is the method to do the consistent conversion?

2) How do I (find) all instances, because this "date" is not an actual attribute, is it a calculated value which changes depending on the two associated models of Contact and Email.

Thanks.

EDIT BELOW:

The resulting output would look like this:

John Johnes "Email subject number1"

Davey Jones "Email subject number 2"

Franklin Rooseveltn "Email subject number 1"

ETC...

A: 

Depending on whether these attributes are stored in a global config or define, or whether they're stored in the database you may be able to do the math in your SQL statement. This is the fastest way.

Otherwise you can do something like this:

Email.find(:all).reject { |email| email.contact.start_date + email.days <= Date.now }

Obviously, I'm missing some details about your data model but hopefully this gives you an idea about how to filter easily.

Chuck Vose
Hi, trying to implement yours, lost on the reject method and the block....can you point me somewhere to RTFM. It seems like an interesting way to do this...
Angela
+1  A: 

You can add a index method to your EmailsController:

class EmailsController < ApplicationController
  def index

    @contact_emails = ContactEmail.all(:include => [:contact, :email], 
     :conditions => ["contacts.created_at <= DATE_SUB(?, INTERVAL 
                             emails.days DAY)", 
     params[:due_date])
    # now you can access the email as
    # contact_email.email
    # contact_email.contact

  end
end

Link to with the due date:

link_to("Due today", emails_path(:due_date => Date.today))

Edit 1

To get the list emails due today:

  def index
    @emails = Emails.all(:conditions => [ " EXISTS ( 
                                   SELECT * 
                                   FROM   contacts A 
                                   WHERE  A.start_date = DATE_SUB(?, 
                                                INTERVAL emails.days DAY)
                                  )", params[:due_date].to_date)    
  end

The query above expects the start_date to be a Date field.

Edit 2

Query for returning the data from contact and emails:

  def index
    joins = Contact.send(:sanitize_sql_array, 
               ["JOIN emails AS emails ON contacts.start_date = 
                    DATE_SUB(?, INTERVAL emails.days DAY)",
                params[:due_date].to_date 
               ])

    @contacts = Contact.all(:joins => joins, 
                :select => "contacts.*, emails.subject AS email_subject") 
  end

Now you can iterate through contacts

@contacts.each do |contact|
  contact.first_name #John
  contact.last_name #Clive
  contact.email_subject #Subject 1
end

If you need more fields from Emails add them to the :select clause(similar to subject).

Edit 3

I have further optimized the solution:

  def index
    joins = Contact.send(

    @contacts = Contact.all(:joins => "JOIN emails AS emails", 
                  :select => "contacts.*, emails.subject AS email_subject",
                  :conditions => ["contacts.start_date = 
                                   DATE_SUB(?, INTERVAL emails.days DAY)",
                                   params[:due_date].to_date 
                               ]
               )

  end
KandadaBoggu
Hi, why is there *two* link_to methods? What does the second link_to do that wouldn't work?
Angela
Hi, this only works once a contacdt_email has been created...but right now it isn't created until it is scheduled. Email mode is the "template" so to speak that needs to get sent at the scheduled time.....
Angela
Two `link_to` methods is a copy+paste error. I have fixed the reply.
KandadaBoggu
Can you describe the functionality again? What is the link between email and contact?
KandadaBoggu
Updated the answer. Take a look.
KandadaBoggu
I think that looks like it would work, let me try, do I need any other plugin for this or as is? what is FROM contact A do?
Angela
Hi, thanks -- we're close!I want to display the Contact.name and the Email that is due today to that specific contact...I made updates above.
Angela
ah...interesting, I see you made a change...I think I need to learn more about the :joins which I don't....
Angela
New solution is efficient and concise.
KandadaBoggu
I think this is it...it definitely is getting me on the right course, will let you know...
Angela
So, just to clarify, I can still use the link_to as you defined, but use Edit 2?
Angela
I used the following in a new Controller called Todo: def show_date @date = Date.today joins = Contact.send(:sanitize_sql_array, ["JOIN emails ON contacts.start_date = DATE_SUB(?, INTERVAL emails.days DAY)", Date.today.to_date ]) @contacts = Contact.all(:joins => joins, :select => "contacts.*, emails.subject AS email_subject") endI get an error:
Angela
What is the error message? Post the error at Pastie.org.
KandadaBoggu
Updated the answer. I forgot to alias the join table.
KandadaBoggu
I have simplified the solution further. I think it is much better now..
KandadaBoggu