undefined local variable or method `email' for Contact:Class - ruby-on-rails

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

Related

Rails Contact Form - Email Sent, but not receiving in my inbox

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>

Error with simple_form and active_attr

I am using active_attr and simple_form.
When I navigate to the page that should show my form I get the following error:
undefined method `new_record?' for #<Message body: nil, email: nil, name: nil, subject: nil>
Here is my model:
class Message
include ActiveAttr::Model
attribute :name
attribute :email
attribute :subject
attribute :body
validates :name, :email, :subject, :body, :presence => true
validates :email, :format => { :with => %r{.+#.+\..+} }, :allow_blank => true
end
My Controller:
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
And finally my view:
<%= simple_form_for #message, :url => contact_path do |f| %>
<%= f.input :name %>
<%= f.input :email %>
<%= f.input :subject %>
<%= f.input :body %>
<%= f.button :wrapped, :submit %>
<% end %>
Apparently the extra functionality I included to make a wrapped button for twitter bootstrap as found on https://github.com/plataformatec/simple_form/wiki/Twitter-Bootstrap-v2-and-simple_form-v2 broke it.
This error was due to a bug in active_attr that was fixed in v0.7.0. Upgrading resolves the issue.

Contact Form Mailer Undefined Method Error Rails

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.

How to pass hidden parameter to controller in Rails3

I'd like to pass the parameter recipient to controller. I can show it in my view like this:
#recipient.username
How can I pass this value to params[:message][:recipient]? Note that I do not have a model called "Message".
controllers/messages_controller.rb
def deliver
recipient = User.find_by_username(params[:recipient])
subject = params[:subject]
body = params[:body]
current_user.send_message(recipient, body, subject)
redirect_to :controller => 'messages', :action => 'received'
flash[:notice] = "message sent!"
end
views/messages/new.html.erb
<td><%= #recipient.username if #recipient %></td>
<%=form_for :messages, url: url_for( :controller => :messages, :action => :deliver ) do |f| %>
<div class="field">
<%= f.label :subject %><br />
<%= f.text_field :subject %>
</div>
<div class="field">
<%= f.label :body %><br />
<%= f.text_field :body %>
</div>
<div class="actions">
<%= f.submit %>
<% end %>
You could do this by assigning an attr_accessible key for your Recipient and assign it to the form.
form_for :message do |f|
f.hidden_field :recipient_id, :value => #recipient.id.to_i
f.text_field :message
f.submit
end
once you pass this to your create action you are able to check params[:message][:recipient_id]
and pass this to the db.
Have fun

How to create three records using one form? And how to show validation errors for them?

Bassicaly my problem what to do if i have 3 forms and one submit button.
I want to create a form which sends email to each recipient and then create new record in free_registration_coupons table.
I need validation of email for this form.
Model FreeRegistrationCoupon: recipient_email, token, sender_id
For now i have this:
class FreeRegistrationCouponsController < ApplicationController
def send_invitations
emails = [params[:recipient_email_1], params[:recipient_email_2], params[:recipient_email_3]]
emails.reject!{ |e| e.eql?("") }
if emails.present?
emails.each do |e|
FreeRegistrationCoupon.create(:recipient_email => e, :sender_id => current_user.id)
#MAILER
end
redirect_to root_path, :notice => "You just send #{emails.size} invitations!"
else
redirect_to(:back)
end
end
end
class FreeRegistrationCoupon < ActiveRecord::Base
before_save :generate_token
attr_accessor :recipient_email, :sender_id
validates :recipient_email, :presence => true, :email => true
def generate_token
self.token = SecureRandom.hex
end
end
This is form which is in other controller CarsController#confirm:
<%= form_tag :controller => 'free_registration_coupons', :action => "send_invitations" do %>
<!-- errors -->
<%= label_tag :recipient_email_1 %>
<%= text_field_tag :recipient_email_1 %>
<%= label_tag :recipient_email_2 %>
<%= text_field_tag :recipient_email_2 %>
<%= label_tag :recipient_email_3 %>
<%= text_field_tag :recipient_email_3 %>
<%= submit_tag %>
<% end %>
I think you should have defined your form using:
<%= form_tag :controller => 'free_registration_coupons', :action => "send_invitations" do %>
<%= #error_message %>
<%= label_tag "recipient_email[1]" %>
<%= text_field_tag "recipient_email[1]" %>
<%= label_tag "recipient_email[2]" %>
<%= text_field_tag "recipient_email[2]" %>
<%= label_tag "recipient_email[3]" %>
<%= text_field_tag "recipient_email[3]" %>
<%= submit_tag %>
<% end %>
This way it will be easier to treat all email address on your controller and you can track those errors to display them afterwards:
class FreeRegistrationCouponsController < ApplicationController
def send_invitations
emails = params[:recipient_email]
emails.reject!{ |param, value| value.eql?("") }
errors = []
if emails.any?
emails.each do |param, value|
validation_result = FreeRegistrationCoupon.save(:recipient_email => value, :sender_id => current_user.id)
#MAILER
end
redirect_to root_path, :notice => "You just send #{emails.size} invitations!"
else
#error_message = "You have to include, at least, one e-mail address!"
render :name_of_the_action_that_called_send_invitations
end
end
end
I didnt test this code. Hope it helps!

Resources