I'm trying to build a contact form in Rails without storing the mails in my database. But I'm getting an undefined method 'name' for nil:NilClass error when I send the form.
My MessagesController
def create
#message = Message.new(message_params)
if #message.valid?
# TODO send message here
Messages.new_messages_email(#mailer).deliver
redirect_to root_url, notice: "Message sent! Thank you for contacting us."
else
redirect_to root_url, notice: "Something went wrong, try again!"
end
end
private
def message_params
params.require(:message).permit(
:name,
:message,
:email
)
end
My Messages model
class Message
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :name, :email, :message
validates_presence_of :name
validates :email, :email_format => {:message => 'is not looking good'}
validates_length_of :message, :maximum => 500
def initialize(attributes = {})
attributes.each do |name, value|
send("#{name}=", value)
end
end
def persisted?
false
end
end
The email body
!!!
%html
%body
%p
= #mailer.name
Schreef het volgende:
%p= #mailer.message
%p= #mailer.email
And in my routes I have
resources :messages
I forgot to post my Messages mailer
class Messages < ActionMailer::Base
default from: "info#domein.nl"
def new_messages_email(mailer)
#mailer = mailer
mail(to: 'peter#no-illusions.nl',
subject: 'Iemand wilt contact met U')
end
end
For completion my form,
= form_for #message do |f|
.field
%br/
= f.text_field :name, :placeholder => "Naam"
.field
%br/
= f.text_field :email, :placeholder => "Emailadres"
.field
%br/
= f.text_area :message, :rows => 5, :placeholder => "Uw bericht"
.actions= f.submit "Verstuur bericht", :id => "submit"
In my MessagesController I define the paramaters for the create function, but there's something I'm doing wrong, forgetting or overlooking which causes the error.
In your controller should be probably:
Messages.new_messages_email(#message).deliver # not #mailer
Besides that, you have to reinitialize #message within your mailer, e.g:
class Messages < ActionMailer::Base
def new_messages_email(msg)
#message = msg
end
end
Related
Model User:
class User < ApplicationRecord
has_one :address, foreign_key: :user_id
accepts_nested_attributes_for :address
end
Model Address
class Address < ApplicationRecord
belongs_to :user, optional: true
end
Controller User, everything happen here
class UsersController < ApplicationController
def home # method which I use to display form
#user = User.find_by :id => session[:id]
end
def update # method for updating data
#user = User.find(session[:id])
if #user.update(user_params)
flash[:notice] = "Update successfully"
redirect_to home_path
else
flash[:error] = "Can not update"
redirect_to home_path
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password, images_attributes: [:image_link, :image_description], address_attributes: [:city, :street, :home_number, :post_code, :country])
end
end
Updating form:
<%= form_for #user, :html => { :id => "update-form", :class => "update-form"} do |f| %>
<%= f.text_field :name %>
<%= f.text_field :email %>
<%= f.fields_for :address do |a| %>
<%= a.text_field :city %>
<%= a.text_field :street %>
<%= a.number_field :home_number %>
<%= a.text_field :post_code %>
<%= a.text_field :country %>
<% end %>
<%= f.submit %>
<% end %>
When I submitting my form, it shows me everything is fine, I mean "Update successfully", but in database its looks like new record is added to address table, but user table is updated properly. Can someone give me explanation why? I am looking answers in google but nothing helps me.
When I submitting my form, it shows me everything is fine, I mean
"Update successfully", but in database its looks like new record is
added to address table, but user table is updated properly. Can
someone give me explanation why?
This is due to the nature of strong params. It expects :id to be permitted for the nested_attributes to update properly, else a new record is created instead. Permit the :id and you are good to go.
def user_params
params.require(:user).permit(:name, :email, :password, images_attributes: [:id, :image_link, :image_description], address_attributes: [:id, :city, :street, :home_number, :post_code, :country])
end
try below code in your controller:
class UsersController < ApplicationController
def home # method which I use to display form
#user = User.find_by :id => session[:id]
end
def update # method for updating data
#user = User.find(session[:id])
if #user.update(user_params)
flash[:notice] = "Update successfully"
redirect_to home_path
else
flash[:error] = "Can not update"
redirect_to home_path
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password, images_attributes: [:image_link, :image_description], address_attributes: [:id, :city, :street, :home_number, :post_code, :country])
end
end
I'm trying to make a contact form for Rails 4. But there're only tutorials for Rails 3.
But I got this error:
undefined method `name' for #<Message:0xa461fcc>
As I can understand it can't "see" the model.
index.html.erb
<%= form_for Message.new, :url => new_contact_path do |form| %>
<fieldset class="fields">
<div class="field">
<%= form.label :name %>
<%= form.text_field :name %>
</div>
... same fieldsets...
<fieldset class="actions">
<%= form.submit "Send" %>
</fieldset>
<% end %>
in my model message.rb i got:
class Message
extend ActiveModel::Naming
include ActiveModel::Conversion
include ActiveModel::Validations
include ActionView::Helpers::TextHelper
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
and in routes i just got:
resources :contact
That's the controller code:
class ContactController < ApplicationController
def new
#message = Message.new
end
def create
#message = Message.new(contact_params)
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
private
# Never trust parameters from the scary internet, only allow the white list through.
def contact_params
params.require(:message).permit(:name, :email, :subject, :body)
end
end
Thanks in advance!
You need to add attr_accessor :name, :email, :subject, :and_so_on to your class to that these methods are defined.
When using form.label, Rails will try doing your_message.label, but this method is not defined since you're not using active record but only few bits from active model.
Using attribute accessors should do the trick.
First off, i know attr_accessible is deprecated in Rails 4, but what about attr_accessor?
When you hit submit it's returning a "Template is Missing" error, but that's because its hitting an error somewhere in the send proccess then just trying to return "connect#create" which doesn't exist as a physical page.
When i check the log files, I am getting a 500 internal server error when trying to send a contact form, and I'm not sure if using attr_accessor in Rails 4 is the culprit. Is there a newer way to write this?
class Message
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :name, :email, :phone, :subject, :company, :title, :market, :body
validates :name, :email, :subject, :company, :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 above is the message model for the contact form:
Is it something within the process of sending the data?
The rest of the code for the contact mail functionality is:
Contact Mailer
class ContactMailer< ActionMailer::Base
default :from => "noreply#test.com"
default :to => "{{MY EMAIL}}"
def new_message(message)
#message = message
mail(:subject => "Test Message")
end
end
In /views/contact_mailer/ there is a new_message.text.erb file:
Name: <%= #message.name %>
Email: <%= #message.email %>
Phone: <%= #message.phone %>
Subject: <%= #message.subject %>
Company: <%= #message.company %>
Title: <%= #message.title %>
Market: <%= #message.market %>
Body: <%= #message.body %>
My Routes are:
match 'connect' => 'connect#index', :as => 'connect', :via => :get
match 'connect' => 'connect#create', :as => 'connectpost', :via => :post
The connect page controller:
class ConnectController < ApplicationController
def index
#message = Message.new
end
def create
#message = Message.new(params[:message])
if #message.valid?
NotificationsMailer.new_message(#message).deliver
redirect_to(connect_path, :notice => "Message was successfully sent.")
else
flash.now.alert = "Please fill all fields."
render :new
end
end
end
And finally....the SMTP settings in /config/initializers/smtp_settings.rb
ActionMailer::Base.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "{{SITE DOMAIN}}",
:user_name => "{{GMAIL EMAIL}}",
:password => "{{GMAIL EMAIL PASSWORD}}",
:authentication => "plain",
:enable_starttls_auto => true
}
My ConnectController#Create was trying to initialize
NotificationMailers.new_message()
But it needed to be:
ContactMailer.new_message()
I have no idea why the tutorial I followed would have the wrong class name there...but that was the issue.
Thanks all.
attr_accessor, attr_writer and attr_reader are all part of vanilla core Ruby and are helper methods for Modules and Classes.
They work fine in Ruby 2.0, so you'll have to mark them off your suspect list.
This question already has answers here:
Adding a string in front of a parameter for a form
(2 answers)
Closed 8 years ago.
I can't seem to figure this out or find a solution to this anywhere...which is crazy to me since i feel like its pretty common and simple
I want to add a little message that my client will see when the user sends them a request through the form and then it goes to an external API where they can see created tickets.
so right now my client sees
John Doe
but i want them to see
Web inquiry from John Doe
So i need to send the "Web inquiry from" part through the form
i've tried to interpolate it in the form
= f.text_field "Web inquiry from #{:subject}"
that didnt work
i've tried to add a value (not the way i want to go but i tried it anyway)
= f.text_field :subject, value: "Web inquiry from #{f.object.subject}"
that did not work either
i've tried to place it in the model
def post_tickets(params)
client.subject = "Hello from, " + client.subject
end
I'm new to rails so if you could be specific as possible that would be helpful...please dont say just do it in the controller.....thank you in advanced
here is my form
= form_for(:contacts, url: contacts_path) do |f|
= f.error_messages
= f.label :subject, "Name"
%span{style: 'color: red'} *
= f.text_field :subject, class: "text_field width_100_percent"
%br
%br
= f.label "Email"
%span{style: 'color: red'} *
%br
= f.email_field :email, class: "text_field width_100_percent"
%br
%br
= f.label "Question(s), and/or feedback"
%span{style: 'color: red'} *
%br
= f.text_area :description, class: "text_field width_100_percent", style: 'height: 100px;'
%br
%br
= f.submit "Submit", class: 'btn btn-warning'
here is my controller
class Website::ContactsController < Website::WebsiteApplicationController
def new
#contacts = Form.new
end
def create
#contacts = Form.new(params[:contacts])
#contacts.post_tickets(params[:contacts])
if #contacts.valid?
flash[:success] = "Message sent! Thank you for conacting us."
redirect_to new_contact_path
else
flash[:alert] = "Please fill in the required fields"
render action: 'new'
end
end
end
here is my model
class Form
include ActiveModel::Validations
include ActiveModel::Conversion
include ActiveModel::Translation
extend ActiveModel::Naming
attr_accessor :config, :client, :subject, :email, :custom_field_phone_number_28445,
:custom_field_name_28445, :custom_field_company_28445, :description,
:custom_field
validates_presence_of :subject, :message => '^Please enter your name'
validates_presence_of :description, :message => '^Question(s), and/or feedback can not be blank'
validates :email, presence: true
validates_format_of :email, :with => /^[-a-z0-9_+\.]+\#([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i
def initialize(attributes = {})
attributes.each do |name, value|
#attributes = attributes
end
self.config = YAML.load_file("#{Rails.root}/config/fresh_desk.yml")[Rails.env]
self.client = Freshdesk.new(config[:url], config[:api_key], config[:password])
end
def read_attribute_for_validation(key)
#attributes[key]
end
def post_tickets(params)
client.post_tickets(params)
end
def persisted?
false
end
end
def post_tickets(params)
# prepend to the params['subject'] just before posting
client.post_tickets "Web enquiry from #{params['subject']}"
end
I'm trying to add a contact form for my Rails 3.1.3 application using this tutorial. However at the end when I try to load my contact page, I get the error:
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.[]
It says it occurs on line 1 of this code block on the new.html.haml page:
= form_for #message, :url => { :action=>"new", :controller=>"contact"} do |form|
%fieldset.fields
.field
= form.label :name
= form.text_field :name
.field
= form.label :email
= form.text_field :email
.field
= form.label :body
= form.text_area :body
%fieldset.actions
= form.submit "Send"
My controller looks like this:
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
Model looks like this:
class Message < ActiveRecord::Base
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :name, :email, :body
validates :name, :email, :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
Why would I be getting that error and how do I fix it? Thanks!
do you add the routes as mention in the tutorial ?
match 'contact' => 'contact#new', :as => 'contact', :via => :get
match 'contact' => 'contact#create', :as => 'contact', :via => :post
Beside you can just use in ur form as
<%= form_for #message, :url => contact_path do |form| %>
If you are using separate forms for new and edit actions, you can this in new.html.haml
= form_for :message, :url => { :action=>"new", :controller=>"contact"} do |form|
or
= form_for :message, #message, :url => { :action=>"new", :controller=>"contact"} do |form|