I am new to rails. I have created an app and a simple contact form. When I fill the contact form out it seems to submit everything fine. I don't get any errors, and the console shows that it worked.
However I am not receiving these emails in my inbox or spam folder. Can anyone tell me what I am doing wrong?
I followed this tutorial
Routes
match '/contacts', to: 'contacts#new', via: 'get'
resources "contacts", only: [:new, :create]
Contacts Controller
class ContactsController < ApplicationController
def new
#contact = Contact.new
end
def create
#contact = Contact.new(params[:contact])
#contact.request = request
if #contact.deliver
redirect_to root_path
flash.now[:notice] = 'Thank you for your message. We will contact you soon!'
else
flash.now[:error] = 'Cannot send message.'
render :new
end
end
end
Model
class Contact < MailForm::Base
attribute :name, :validate => true
attribute :email, :validate => /\A([\w\.%\+\-]+)#([\w\-]+\.)+([\w]{2,})\z/i
attribute :message
attribute :nickname, :captcha => true
# Declare the e-mail headers. It accepts anything the mail method
# in ActionMailer accepts.
def headers
{
:subject => "My Contact Form",
:to => "myemail#gmail.com",
:from => %("#{name}" <#{email}>)
}
end
end
New.html.erb
<div align="center">
<h3>Send A message to Us</h3>
<%= simple_form_for #contact, :html => {:class => 'form-horizontal' } do |f| %>
<%= f.input :name, :required => true %>
<%= f.input :email, :required => true %>
<%= f.input :message, :as => :text, :required => true %>
<div class= "hidden">
<%= f.input :nickname, :hint => 'Leave this field blank!' %>
</div>
<div>
</br>
<%= f.button :submit, 'Send message', :class=> "btn btn-primary" %>
</div>
<% end %>
</div>
Create.html.erb
<div>
<% flash.each do |key, value| %>
<div>
×
<%= value %>
</div>
<% end %>
</div>
Related
I would like to use ruby mail_form and Heroku Sendgrid to allow users to send me an email. I have set up the following Contact class in apps/models/contact.rb
class Contact < MailForm::Base
attribute name, :validate => true
attribute email, :validate => /\A([\w\.%\+\-]+)#([\w\-]+\.)+([\w]{2,})\z/i
attribute message, :validate => true
attribute nickname,:captcha => true
def headers
{
:subject => "Contact Form",
:to => "example#email.com",
:from => %("#{name}" <#{email}>)
}
end
end
However, when I visit the page where I have set up my form, I receive the following error message:
undefined local variable or method `email' for Contact:Class
Commenting out the email attribute defined in my Contact class produces similar errors in subsequent attributes message: and nickname:
Below is my Contacts controller, contacts_controller.rb
class ContactsController < ApplicationController
def new
#contact = Contact.new
end
def create
#contact = Contact.new(params[:contact])
#contact.request = request
if #contact.deliver
flash.now[:error] = nil
else
flash.now[:error] = "Oops! There was an error."
render :new
end
end
end
and my form, new.html.erb
<% provide(:title, "Contact") %>
<h1>Contact</h1>
<%= form_for #contact do |f| %>
<%= f.label :name %><br>
<%= f.text_field :name, required: true %>
<br>
<%= f.label :email %><br>
<%= f.text_field :email, required: true %>
<br>
<%= f.label :message %><br>
<%= f.text_area :message, as: :text %>
<div class="hidden">
<%= f.label :nickname %><br>
<%= f.text_field :nickname, hint: "Leave this field blank." %>
</div>
<%= f.submit "Send Message", class: "btn" %>
<% end %>
<ul class="pager">
<li>Previous</li>
</ul>
Any help or suggestions would be greatly appreciated!
You omitted double quotes in the from option.
def headers
{
:subject => "Contact Form",
:to => "example#email.com",
:from => %("#{name}" <#{email}>)
}
end
Using the Mail_form Gem in rails, I can verify that my mail configuration is correct; however I don't receive any errors in my logs.
contact.rb [app/models/contact.rb]
class Contact < MailForm::Base
include MailForm::Delivery
attribute :name, :validate => true
attribute :email, :validate => /\A([\w\.%\+\-]+)#([\w\-]+\.)+([\w]{2,})\z/i
attribute :message
attribute :nickname, :captcha => false
# Declare the e-mail headers. It accepts anything the mail method
# in ActionMailer accepts.
def headers
{
:subject => "IT Site Contact",
:to => "kompinski#gmail.com",
:from => %("#{name}" <#{email}>)
}
end
end
contacts_controller.rb
class ContactsController < ApplicationController
def new
#contact = Contact.new(params[:contact])
end
def create
#contact = Contact.new(params[:contact])
#contact.request = request
#contact.deliver
end
end
routes.rb
resources :contacts, only: [:new, :create]
get 'contact' => 'contacts#new'
post 'contact' => 'contacts#create'
new.html.erb [/views/contacts/new.html.erb]
<div class="container">
<div class="col-md-6"><h2>Contact us</h2>
<hr />
<form role="form">
<%= twitter_bootstrap_form_for #contact, url: new_contact_path, method: :post do |f| %>
<div class="medium">
</div>
<div class="medium">
<%= f.text_field :name, :required => true %>
</div>
<div class="medium">
<%= f.email_field :email, :required => false %>
</div>
<div class="medium">
<%= f.text_area :message, :as => :text, :required => true %>
</div>
<div class="btn">
<%= f.submit 'Submit' %>
<% end %>
</div>
</form>
</div>
</div>
** Edit **
Also I can send it directly from the form by using Contact.new(params[:contact]).deliver, but only when resubmit the address; however when I load the page containing the form it indicates 'undefined method `model_name' for TrueClass:Class'
This code worked for my controller where the issue seemed to be:
def new
#contact = Contact.new
if
Contact.new(params[:contact]).deliver
redirect_to '/contacts/thanks', :alert => ["Yeah!"]
end
This is a pretty basic question, but I'm having difficulty incorporating it in to my application. I've looked at other similar questions on SO, but they all are using the contact page as a separate page.
I have a front-end of a Rails app that is just a small public facing site using stellar.js for parallax scrolling.
At the last part of the page, I would like to have a "Contact Us" form, but I'm getting a
NoMethodError in Welcome#index undefined method `model_name' for NilClass:Class
Here are the related files:
routes.rb
TestApp::Application.routes.draw do
get "welcome/index"
root :to => 'welcome#index'
match 'contact' => 'contact#new', :as => 'contact', :via => :get
match 'contact' => 'contact#create', :as => 'contact', :via => :post
app/views/welcome/index.html.erb
<%= render "contact" %>
The partial for the contact section of the page app/views/welcome/_contact.html.erb
<%= form_for #message, :url => contact_path do |form| %>
<fieldset class="fields">
<div class="field">
<%= form.label :name %>
<%= form.text_field :name %>
</div>
<div class="field">
<%= form.label :email %>
<%= form.text_field :email %>
</div>
<div class="field">
<%= form.label :subject %>
<%= form.text_field :subject %>
</div>
<div class="field">
<%= form.label :body %>
<%= form.text_area :body %>
</div>
</fieldset>
<fieldset class="actions">
<%= form.submit "Send" %>
</fieldset>
<% end %>
app/controllers/contact_controller.rb
class ContactController < ApplicationController
def new
#message = Message.new
end
def create
#message = Message.new(params[:message])
if #message.valid?
NotificationsMailer.new_message(#message).deliver
redirect_to(root_path, :notice => "Message was successfully sent.")
else
flash.now.alert = "Please fill all fields."
render :new
end
end
end
message.rb
class Message
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :name, :email, :subject, :body
validates :name, :email, :subject, :body, :presence => true
validates :email, :format => { :with => %r{.+#.+\..+} }, :allow_blank => true
def initialize(attributes = {})
attributes.each do |name, value|
send("#{name}=", value)
end
end
def persisted?
false
end
end
The question is what do I need to do to make this form to function correctly in the welcome#index view?
You need to have #message = Message.new defined in every action that needs #message to be present.
So that means you need this in WelcomeController:
def index
#message = Message.new
end
A shortcut is to just add it to the top of the partial in case it's not set:
<% #message ||= Message.new %>
(But you need to decide if mixing in calls to the model within your views is your style. Some devs don't have a problem with this, and some do.)
You can change following things:
In routes:
Remove:
match 'contact' => 'contact#new', :as => 'contact', :via => :get
match 'contact' => 'contact#create', :as => 'contact', :via => :post
Add:
resources :contact # It will add 7 default REST routes and standard practice model name should be plural if you created your model with singular then keep it singular
In _contact.html.erb partial form path needs to be new_contact_path
<%= form_for Message.new, :url => contact_path do |form| %>
class Message should inherit ActiveRecord::Base
class Message < ActiveRecord::Base
end
In create action else part should be:
if #message.valid?
NotificationsMailer.new_message(#message).deliver
redirect_to(root_path, :notice => "Message was successfully sent.")
else
flash.now.alert = "Please fill all fields."
render :template => "welcome/index"
end
I have a User model and a Company model linked like this:
class User < ActiveRecord::Base
belongs_to :company
accepts_nested_attributes_for :company
end
class Company < ActiveRecord::Base
has_many :users
end
On the sign in page, I want the user to set up both his info (mail, password) and his company info (several fields). So my form looks like this:
<%= simple_form_for #user, :html => { :class => 'form-horizontal' } do |f| %>
<%= f.input :email, :required => true, :placeholder => "user#domain.com" %>
<%= f.input :password, :required => true %>
<%= f.input :password_confirmation, :required => true %>
<h2>Company info</h2>
<%= simple_fields_for :company, :html => { :class => 'form-horizontal' } do |fa| %>
<%= fa.input :name %>
<%= fa.input :url %>
<%= fa.input :description, :as => :text, :input_html => { :cols => 60, :rows => 3 } %>
<%= fa.input :logo %>
<%= fa.input :industry %>
<%= fa.input :headquarters %>
<% end %>
<div class="form-actions">
<%= f.submit nil, :class => 'btn btn-primary' %>
<%= link_to t('.cancel', :default => t("helpers.links.cancel")),
root_url, :class => 'btn' %>
</div>
<% end %>
My user model has a company_id:integer field. So logically, when I sign in the user, the first thing to do is to create the Company before the User and then give to the user creation model the appropriate company_id. So I wrote this:
class UsersController < ApplicationController
before_create :create_company
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
redirect_to root_url, :notice => "Registration successful."
else
render :action => 'new'
end
end
private
def create_company
#company = Company.new(params[:company])
if #company.save
self.company_id = #company.id
else
render :action => 'new'
end
end
end
Problem is: when accessing /users/new I get this error:
undefined method `before_create' for UsersController:Class
What's going wrong? I checked, before_create has not been deprecated, I'm in Rails 3.2.8. This is probably something stupid with my create_company method but I can't figure why...
Thanks a lot for helping!
before_create is a hook method belonging to ActiveRecord
before_filter is a hook method belonging to Controller.
so I suggest you to re-build your code after you make clear which is which. ^_^
I have been having some serious trouble all weekend trying to get this basic contact form to work correctly.
Effectively I want the user to be able to complete the form, hit send and have the message send straight to a predefined email address.
The error I am continually getting is:
NoMethodError in Messages#new
Showing C:/Sites/jobapp_v2/app/views/messages/new.html.erb where line #1 raised:
undefined method `[]' for nil:NilClass
Extracted source (around line #1):
1: <%= form_for #message, :url => contact_path do |f| %>
2:
3: <div class="field">
4: <%= f.label :name %>
I have the following setup:
Messages controller
class MessagesController < ApplicationController
def new
#user = current_user
#message = Message.new
end
def create
#message = Message.new(params[:message])
if #message.valid?
NotificationsMailer.new_message(#message).deliver
redirect_to(root_path, :notice => "Message was successfully sent.")
else
flash.now.alert = "Please fill all fields."
render :new
end
end
end
Message Model
class Message < ActiveRecord::Base
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :name, :email, :subject, :body
validates :name, :email, :subject, :body, :presence => true
validates :email, :format => { :with => %r{.+#.+\..+} }, :allow_blank => true
def initialize(attributes = {})
attributes.each do |name, value|
send("#{name}=", value)
end
end
def persisted?
false
end
end
Routes.rb
JobappV2::Application.routes.draw do
devise_for :users
resources :newsletters
match "contact" => "messages#new", :as => "contact", :via => :get
match "contact" => "messages#create", :as => "contact", :via => :post
get "pages/about"
get "pages/contact"
get "pages/terms"
resources :jobs
resources :users do
resources :jobs
end
root :to => 'jobs#index'
end
NotificationsMailer.rb
class NotificationsMailer < ActionMailer::Base
default :from => "advertise#artisanmag.co.uk"
default :to => "tom.pinchen#artisanmag.co.uk"
def new_message(message)
#message = message
mail(:subject => "Hello")
end
end
Views/notification_mailer/new_message.text.erb
Name: <%= #message.name %>
Email: <%= #message.email %>
Subject: <%= #message.subject %>
Body: <%= #message.body %>
Views/messages/new.html.erb
<%= form_for #message, :url => contact_path do |f| %>
<div class="field">
<%= f.label :name %>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :email %>
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :subject %>
<%= f.text_field :subject %>
</div>
<div class="field">
<%= f.label :body %>
<%= f.text_area :body %>
</div>
<%= f.submit "Send" %>
<% end %>
I really for can't work out at all what is causing this undefined method error so any help people can offer would really be much appreciated! Thanks in Advance :)
The way you have hooked things up, you don't need :url => contact_path
<%= form_for #message do |f| %>
will work just fine.