views:

148

answers:

4

Using the code generated by restful_authentication, we usually get 'localhost' as the URL in the sign up and activation mails. I am trying to create something like this instead:

def signup_notification(user, host)
  setup_email(user)
  @subject    += 'Please activate your new account'

  @body[:url]  = "http://#{host}/activate/#{user.activation_code}"
end

However, since the actual call to deliver the mail is in an Observer, I can't do this:

UserMailer.deliver_signup_notification(user, request.host_with_port)

Since the request method is not available in models. What is the best way to go about doing this?

I thought about storing URLs per domain in a YAML file and then loading it on startup but then the ports may change, so it wouldn't work.

Alternatively, I thought about creating a static class variable somewhere that is set upon loading up the application, but I don't know how to go about doing this. Is the request method available for initializers?

A: 

The hostname your server is accessed by is found in the Host header of the request. You shouldn't have access to it in the models (assuming rails is sane). But if you can access request objects in the controllers you can insert that value to your model field when you pull the model objects from db.

Vasil
So basically, I should add a virtual attribute to the model? I'll try that out.
Jaryl
+1  A: 

Using ActiveMailer, i set this in the config/envrionments/production.rb

config.action_mailer.default_url_options = { :host => "my.host.com" }

In the model app/models/event_mailer.rb

def new_event(event)
 recipients EventMailer::NO_REPLY
 bcc   event.emails('new_event')
 from        EventMailer::FROM_EMAIL
 subject     "#{EventMailer::SUBJECT_HEADER} Event Updated :: #{event.title}"
 content_type "text/plain"
 body        :event => event
end

And then in the mailer view app/views/event_mailer/new_event.rb

You can view the event by going to: <%= url_for(:controller => "events", :action => "show", :id => @event.id, :only_path => false) %>

Which Generates in the mail:

You can view the event by going to: http://my.host.com/events/11
Dan McNevin
Thanks for this, it works great, but what's the purpose of: config.action_mailer.default_url_options = { :host => "my.host.com" }Doesn't the url_for method generate the URL using the production host name on a production server?
Jaryl
Ignore my last comment, I need to be able to run this several machines, and thus we won't have the same local dns settings as well as ports, so this might not work so well.
Jaryl
+1  A: 

I got a same problem too and here's what I've done

  1. in user model I add :host to attr_accessible, then I add this method

    def host=(value)
      write_attribute :host, value
    end
    
  2. in user controller, in the methods that sends email like create and activate I put

    @user.host = request.host_with_port

since I'm still a noob-on-rails so I really hope someone will come up with a best-practice solution for this problem.

William Notowidagdo
I'm accepting this answer not because it is the best (it's not very Rails-like) but because it best fits my needs. This problem should be fixed since it happens when we have multiple developers and maybe even working with subdomains and everything.
Jaryl
+1  A: 

try current_request plugin, described at http://codeshooter.wordpress.com/2009/08/

worked for me

Pavel K.
This looks like a better solution. Plus, I can set up a fall back so that mails sent not via a request action (say through a rake task) can use a default host name instead.
Jaryl