Re: How to make a simple Contact Form

I've got an error on this last tutorial paper:

It broke: No rhtml, rxml, rjs or delegate template found for contact_message

It seems that the Mailer model can't find a view like 'views/mailer/contact_message.rhtml'. Can anybody see the reason?

cheers,

Alex

Re: How to make a simple Contact Form

It was a configuration problem in environment.rb with a desactivated :action_mailer module.

Re: How to make a simple Contact Form

Hi,

I made my contact form according to this tutorial posted by dawie, and it works very reliably. However, it is far too complicated in the long run because it makes me create additional models just to get the benefit of ActiveRecord's validation features.

So, if you need a simple contact form for your website, just do this:

"contact.rhtml" (the contact form):

<%= start_form_tag :action => 'send_contact_form'  %>
 
    <h2>Name:</h2>       
    <%= text_field "author", "name" %>
 
    <h2>E-Mail:</h2>
    <%= text_field "author", "email" %>
 
    <h2>Message:</h2>           
    <%= text_area    "author", "message" %><br/>
   
    <%= submit_tag "Send" %>
   
<%= end_form_tag %>

Controller:
  def send_contact_form 
    if request.post?
      Mailer::deliver_message(params[:author])
      redirect_to :action => 'contact'
      flash[:notice] = "Thanks for your message!"
    end
  end

"mailer.rb" (model):
class Mailer < ActionMailer::Base
   
  def message(author)
    @recipients       = "me@mysite.com"
    @from             = author[:email]
    @subject          = "New message"
    @body['name']     = author[:name]
    @body['email']    = author[:email]
    @body['message']  = author[:message]
  end

end


"message.rhtml" (the e-mail that will be sent to you):
The following message has just been sent via the contact form on your website:

From: <%= @name %>

Message: <%= @message %>


Add this to the bottom of your "environment.rb" file:
  ActionMailer::Base.delivery_method = :sendmail
  ActionMailer::Base.server_settings = {
  :address          => "mail.mysite.com", #insert YOUR address here
  :domain           => "mysite.com",
  :port             => 25,
  :authentication   => :login,
  :user_name        => "myusername", #insert YOUR username here
  :password         => "mypassword" #insert YOUR password here
    }
  ActionMailer::Base.perform_deliveries = true
  ActionMailer::Base.raise_delivery_errors = true
  ActionMailer::Base.default_charset = "utf-8"

I think this is probably the simplest way to create a working contact form for your website.
However, it does no validation whatsoever, so users can easily send you empty messages by mistake.

I am currently trying to implement "real-time validation" using Ajax, but have no idea where to start. I want the form field to get validated before the user even hits the submit button. How can I achieve this effect?
Can anybody hint me into the right direction?

Last edited by Pixelateur (2007-01-02 17:50:10)

Re: How to make a simple Contact Form

Hi there,
I have tried all the above examples in both testing an in production environments. 
the one that seemed to make the most sense to me was pb hogans 'tableless' valid contact form, that dawie linked to.
I have it running w/ out error and have tested it both locally and on live servers and am constantly having the same problem.  when the submit button is hit the correct running but the form just reloads no success or failure message, no email is sent.
I am lost and getting ready to just connect to a php from via the rails controller.
totally confused and pretty ready to throw in the rails towel.

JOsh

since, forum sigs  are a good way to have a soap box, here I go.
A BBCode WYSIWYG would be a great addition to this site.

Re: How to make a simple Contact Form

Hi Josh,
Sorry, I haven't got a clou here. All I can say is that the code in my previous post (the one above yours) works perfectly fine. You can see it in action on my Website. On my website I am using some Ajax validation techniques, that aren't included in the code above.
In one of my previous projects I followed the tutorial you mention and it still works great. You can see it here: Link

Re: How to make a simple Contact Form

Ok well here is my code as well as a snippet of the log file, of the rendering of the code.  forgive me now for my repetitiveness as some of this is direct cut and paste. (maybe that is my problem).  any one got any clues as to why this is happening?

tableless.rb

class Tableless < ActiveRecord::Base
    def self.columns()
        @columns ||= [];
    end
   
    def self.column(name, sql_type = nil, default = nil, null = true)
        columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default,sql_type.to_s, null)
    end
   
    # override the save method to prevent exceptions.
    def save(validate = true)
        validate ? valid? : true
    end
end

b]mailer.rb[/b]
class Mailer < ActionMailer::Base
  def contact_message(contact)
    @recipients = CONTACT_RECIPIENT
    @from = contact.email_address
    @subject = 'Contact Form Request'
    @body['name'] = contact.name
    @body['city'] = contact.city
    @body['state'] = contact.state
    @body['zip'] = contact.zip
    @body['phone'] = contact.phone
    @body['email'] = contact.email_address
    @body['address'] = contact.address
    @body['message'] = contact.message
  end
end

contact.rb
class Contact < Tableless
    column :name, :string
    column :city, :string
    column :state, :string
    column :phone, :string
    column :email_address, :string
    column :address, :string
    column :zip, :string
    column :message, :text
    validates_presence_of :name, :email_address, :message
end

config.yml
development:
        email:
                server: localhost
                port: 3005
                domain: local_host
                authentication: none
                username:
                password:
                contact_recipient: josh@dontwannagetspamed.com
production:
        email:
                server: localhost
                port: 25
                domain: www.altfoodcompany.com
                authentication: login
                username: ********
                password: ********
                contact_recipient: josh@dontwannagetspamed.com

snippet of environment.rb
c = YAML::load(File.open("#{RAILS_ROOT}/config/config.yml"))
ActionMailer::Base.server_settings = {
    :address => c[RAILS_ENV]['email']['server'],
    :port => c[RAILS_ENV]['email']['port'],
    :domain => c[RAILS_ENV]['email']['domain'],
    :authentication => c[RAILS_ENV]['email']['authentication'],
    :user_name => c[RAILS_ENV]['email']['username'],
    :password => c[RAILS_ENV]['email']['password']
}
CONTACT_RECIPIENT = c[RAILS_ENV]['email']['contact_recipient']

snippet of page_controller.rb
#contact from below here
  def contact
    @contact = Contact.new
  end
   
  def send_contact_request
    @contact = Contact.new(params['contact'])
    if @contact.save
            begin
                Mailer::deliver_contact_message(@contact)
                flash[:notice] = "Success!"
                redirect_to :action=>"contact"
            rescue
                flash[:notice] = "It broke!"
                render :action=>"contact"
        end
        else
            flash[:notice] = "only rendering"
            render :action=>"contact"
    end
    end

contact.rhtml
 <%=error_messages_for "contact" %>
<%= start_form_tag :controller=>"page", :action=>"send_contact_request" %>
<label for='contact[name]'>Name</label> <%= text_field("contact", "name") %><br />
<label for='contact[email_address]'>Email</label> <%= text_field("contact", "email_address") %><br />
<label for='contact[address]'>Address</label> <%= text_field("contact", "address") %><br />
<label for='contact[city]'>City</label> <%= text_field("contact", "city") %><br />
<label for='contact[state]'>State</label> <%= text_field("contact", "state", {"size"=>"5"}) %><br />
<label for='contact[zip]'>Zip</label> <%= text_field("contact", "zip", {"size"=>"10"}) %><br />
<label for='contact[phone]'>Phone</label> <%= text_field("contact", "phone") %><br />
<label for='contact[message]'>Message</label><br /> <%= text_area("contact", "message") %><br />
<%= submit_tag "Send" %>
<%= end_form_tag %>

contact_message.rb
A user has chosen to contact you via your web site.
===================================================
User: <%=@name %>
Email: <%=@email %>
Address: <%=@address %>
City: <%=@city %>
State: <%=@state %>
Zip: <%=@zip %>
Phone: <%=@phone %>
Message:
-----------------------------
<%=@message %>
-----------------------------
Generated at <%=Time.now.to_s %>

the bit of my log file that is processing this.
Processing PageController#send_contact_request (for 72.70.247.236 at 2006-12-11 07:38:09) [POST]
  Session ID: accf939579a63714e320646c00fac327
  Parameters: {"commit"=>"Send", "contact"=>{"name"=>"contact[name]", "city"=>"NOrthampton", "message"=>"heyheymy my", "zip"=>"contact[zip]", "phone"=>"contact[phone]", "address"=>"46 Pine brook Curve", "state"=>"contact[state]", "email_address"=>"josh@dontwanngetspammed.com"}, "action"=>"send_contact_request", "controller"=>"page"}
Rendering actioncontactlayoutfalse within layouts/default
Rendering page/contact
Start rendering component ({:params=>{:styleclass=>"credits"}, :action=>"menu"}):


Processing PageController#menu (for 72.70.247.236 at 2006-12-11 07:38:10) [POST]
  Session ID: accf939579a63714e320646c00fac327
  Parameters: {"styleclass"=>"credits", "action"=>"menu", "id"=>nil, "controller"=>"page"}
Rendering page/menu
Completed in 0.06025 (16 reqs/sec) | Rendering: 0.02245 (37%) | DB: 0.03693 (61%) | 200 OK [http://altfoodcompany.com/page/send_contact_request]


End of component rendering
Completed in 0.28550 (3 reqs/sec) | Rendering: 0.24160 (84%) | DB: 0.03176 (11%) | 200 OK [http://altfoodcompany.com/page/send_contact_request]

since, forum sigs  are a good way to have a soap box, here I go.
A BBCode WYSIWYG would be a great addition to this site.

Re: How to make a simple Contact Form

Hi sanguis,

I spent some time trying to figure out what may be wrong in your code, but to be honest with you I can't see any reason why it should not work. I got into programming only about a year ago, so it's hard for me to give you any advice. All I can say is that I followed the exact same tutorial and it worked great for me.

Re: How to make a simple Contact Form

Timo,
I have been review logs and I believe that is is something to do w/ a server configuration.  I have started dialog w/ my sys admin.  I will post the results when I get them.

JOsh

since, forum sigs  are a good way to have a soap box, here I go.
A BBCode WYSIWYG would be a great addition to this site.

Re: How to make a simple Contact Form

Status update. progress made.
I commented out the rescue options in the controller and am not getting 'proper' in my log files.  I can finally start to route out the problems I have been having.  they actually don't stem  from the contact form code but, part of the template (or theme) manager causing the problem.

any one got any suggestions on how I tell a mailer that it does note need a theme?
btw the theme contoler is part of the CMS, Eribium.

JOsh

Processing PageController#send_contact_request (for 72.70.247.236 at 2006-12-12 17:59:38) [POST]
  Session ID: a0d91d470cbece9a63c20f28f223fc21
  Parameters: {"commit"=>"Send", "contact"=>{"name"=>"contact[name]", "city"=>"contact[city]", "message"=>"contact[message]", "zip"=>"contact[zip]", "phone"=>"contact[phone]", "address"=>"contact[address]", "state"=>"contact[state]", "email_address"=>"example@example.com"}, "action"=>"send_contact_request", "controller"=>"page"}


NoMethodError (undefined method `current_theme' for #<Mailer:0xb78184ac>):
    /vendor/plugins/theme_support/lib/patches/actionview_ex.rb:16:in `render_file'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_view/base.rb:274:in `render'
    /usr/local/lib/ruby/gems/1.8/gems/actionmailer-1.2.5/lib/action_mailer/base.rb:427:in `render'
    /usr/local/lib/ruby/gems/1.8/gems/actionmailer-1.2.5/lib/action_mailer/base.rb:422:in `render_message'
    /usr/local/lib/ruby/gems/1.8/gems/actionmailer-1.2.5/lib/action_mailer/base.rb:370:in `create!'
    /usr/local/lib/ruby/gems/1.8/gems/actionmailer-1.2.5/lib/action_mailer/base.rb:331:in `initialize'
    /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:21:in `new'
    /usr/local/lib/ruby/gems/1.8/gems/actionmailer-1.2.5/lib/action_mailer/base.rb:291:in `method_missing'
    /app/controllers/page_controller.rb:58:in `send_contact_request'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:941:in `perform_action_without_filters'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/filters.rb:368:in `perform_action_without_benchmark'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/benchmarking.rb:69:in `perform_action_without_rescue'
    /usr/local/lib/ruby/1.8/benchmark.rb:293:in `measure'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/benchmarking.rb:69:in `perform_action_without_rescue'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/rescue.rb:82:in `perform_action'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:408:in `process_without_filters'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/filters.rb:377:in `process_without_session_management_support'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/session_management.rb:117:in `process'
    /usr/local/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/dispatcher.rb:38:in `dispatch'
    /usr/local/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/fcgi_handler.rb:150:in `process_request'
    /usr/local/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/fcgi_handler.rb:54:in `process!'
    /usr/local/lib/ruby/gems/1.8/gems/fcgi-0.8.7/lib/fcgi.rb:612:in `each_cgi'
    /usr/local/lib/ruby/gems/1.8/gems/fcgi-0.8.7/lib/fcgi.rb:609:in `each_cgi'
    /usr/local/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/fcgi_handler.rb:53:in `process!'
    /usr/local/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/fcgi_handler.rb:23:in `process!'
    dispatch.fcgi:30

since, forum sigs  are a good way to have a soap box, here I go.
A BBCode WYSIWYG would be a great addition to this site.

Re: How to make a simple Contact Form

i've followed diabatzu....but when i click on button nothing happens .....like its dead.

Re: How to make a simple Contact Form

Hi Josh, sorry that wasn't able to help. Please post a link to your contact form here once you are done. Would like to have a look at it :-)

Re: How to make a simple Contact Form

Sorry, still I am getting error to make a contact form. Can anybody post a detail document which make to send email?

Thanks,

Re: How to make a simple Contact Form

If you are looking for a good javascript form validation script check out YAV. I am currently using it in a project and it works great. It also has good documentation and shows working examples to help you get it up and running quickly.
http://yav.sourceforge.net/en/index.html

Re: How to make a simple Contact Form

I just tried the tableless solution proposed in this thread. It wasnt working at all so I commented out the rescue statement in the controller and following the stack trace I see that the error is in the send_contact_request action.

undefined method `contact_message'

Now to me this makes no sense, because in my entire project, there is no call to this method. The only thing that comes close would be this.

Mailer::deliver_contact_message(@contact)

All problems aside, I am pretty disappointed with how complicated it is to make a simple contact form in Rails. This task is much easier in PHP.

Re: How to make a simple Contact Form

pimpmaster wrote:

undefined method `contact_message'

Now to me this makes no sense, because in my entire project, there is no call to this method. The only thing that comes close would be this.

Mailer::deliver_contact_message(@contact)

All problems aside, I am pretty disappointed with how complicated it is to make a simple contact form in Rails. This task is much easier in PHP.

pimpmaster, the undefined method contact_message is exactly right from deliver_contact_message, it seems complex at first but isn't really - let me see if I can help you out with it...

first setup your environment.rb file with your server settings for sending mail, look previously in the thread for an example, then

1)to send an email with rails you need a model (I usually call this notification) that inherits from ActionMailer::Base
- so -

class Notifications < ActionMailer::Base

2)this class contains method for each of the type of email you want to send, for example...
  def forgot_password(address, password, sent_at = Time.now)
    @subject    = 'Your new login details'
    @body       = {'email' => address, 'password' => password}
    @recipients = address
    @from       = 'no-reply@example.com'
    @sent_on    = sent_at
    @headers    = {}
  end

this is all IN THE MODEL, you might expect it to be in a controller for wahtever reason but it's not, mailers don't usually have controllers themselves (at least I haven't come across them) but they do have views, the view controls the look of the email so we have...

3)this is a the views/notifications/forgot_password.rhtml file...

As per your request a new random password has been created for your account.
Your new password is <%= @password %>

You can now login and change it to something that you'll remember.


as you can see this is using the instance variable @password - that is created from the hash assigned to @body in the forgot_password method in the class/model

4) to send the email all you do is make a method call to deliver_method_name

that is in this case...

Notifications.deliver_forgot_password(email, new_password)

this could be called within a users controller for example


that's it!

Last edited by Baltar (2007-05-02 14:52:44)

Re: How to make a simple Contact Form

Thanks for clarifying this..I am starting to understand how it works.

I am just at a loss on how to make this into a contact page, where people can fill out their name and email with a message (maybe get some CAPTCHA action once its working)

Googling doesn't turn up anything strangely enough

Re: How to make a simple Contact Form

Alright, I didn't want to clutter this thread up with more code, so:

http://pastie.caboo.se/58332

That is how far I have gotten. The form submits and I get the flash message stating it was successful, but I get no mail. I am using the same smtp setting for my current email account to test this, but so far no dice.

Is there something obvious I am missing?

Last edited by pimpmaster (2007-05-02 14:43:29)

Re: How to make a simple Contact Form

God I love pastie! it all looks so neat and tidy! big_smile

I can't see anything immediately wrong, everything looks good from here - if the flash is being set then your begin/rescue block is obvisouly being called OK, which means the deliver_contact_message method must be returning OK - which means it must be something in the actual delivery - one thing to check, in your environment.rb (or in development.rb etc) make sure you have this line uncommented

config.action_mailer.raise_delivery_errors = true

otherwise rails won't raise errors when the mail isn't sent

other than that my advice would be to try it out with an alternate smtp server, I tend to use gmail (even though it takes a bit of extra setting up) because I've had trouble in the past with using my own server's smtp (sometimes it works, other times not)

one last thing I didn't notice in your environment.rb

ActionMailer::Base.delivery_method = :smtp

I don't know whether this is needed when using ActionMailer::Base.smtp_settings as opposed to the old ActionMailer::Base.server_settings but I tend to include it anyway!

hope one of these helps, if not I recommend trying to setup the simplest version (kinda like I outlined before) and get that working before adding on the extra layers you want for your final production app - then when it breaks you can tell where the trouble is coming in

Re: How to make a simple Contact Form

God I love pastie! it all looks so neat and tidy!

Yeah, I have become a real sucker for pastie. I think I will post all of my (longer) code examples like this in the future.

As for my problem, your advice was gold. I tracked the issue down to my email port, which was not set correctly. I also had some syntax errors in one of my controllers. D'oh!

The mail delivers successfully and all is almost perfect. The only weird glitch is the fact that the user's name is not visible in the email.

User:    <%= @name %>
Message: 
-----------------------------
<%= @message %>

-----------------------------
Submitted at <%=Time.now.to_s %>


I dont get it.. the other parameters (message & email) are getting passed along just fine

Re: How to make a simple Contact Form

I figured it out! I just needed to add @body['name'] = contact.name  to the mailer model.

Thanks so much, Baltar! big_smile

Couldnt have done it without you