Rails Contact form, Action_mailer not sending e-mail - ruby-on-rails

I am not really sure what I am doing wrong.
I see that quite many people have similar problems:
Rails contact form not working,
Rails 3 Contact Form, undefined method?,
Contact Us form in Rails 3 and etc.
Even tough I also see that quite many consider this very simple - to build a contact form.
Been trough popular actionmailer guides: http://guides.rubyonrails.org/action_mailer_basics.html,
http://railscasts.com/episodes/206-action-mailer-in-rails-3
I am not really a developer, so I find this quite confusing.
Anyway, I need to build a simple contact form, to just send the message as an email for a email account of mine. I don't want to store the messages in my db.
Here's my code:
/app/models/message.rb
class Message
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :name, :email, :content
def initialize(attributes = {})
attributes.each do |name, value|
send("#{name}=", value)
end
end
def persisted?
false
end
end
app\controllers\messages_controller.rb
class MessagesController < ApplicationController
def new
#message = Message.new
end
def create
#message = Message.new(params[:message])
MessageMailer.send(#message).deliver
flash[:notice] = "Message sent! Thank you for contacting us."
redirect_to root_url
end
end
/app/mailer/message_mailer.rb
class MessageMailer < ActionMailer::Base
default :to => "emils.veveris#thrillengine.com"
def send(message)
#message = message
mail( :subject => " Test ", :from => #message.email ) do |format|
format.text
end
end
end
app/views/messages/new.html.erb
<h1> "Contact Us" </h1>
<%= form_for #message do |f| %>
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>
</p>
<p>
<%= f.label :email %><br />
<%= f.text_field :email %>
</p>
<p>
<%= f.label :content, "Message" %><br />
<%= f.text_area :content %>
</p>
<p><%= f.submit "Send Message" %></p>
<% end %>
app/views/message_mailer/sent.text.erb
Message sent by <%= #message.name %>
<%= #message.content %>
and development.rb
N1::Application.configure do
# Don't care if the mailer can't send
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
end
I don't see any errors in log file and I don't receive any error messages.
The mail is just not delivered.
Can You please tell me what I am doing wrong?
Thanks!

This is a little old but maybe some of the concepts can help you...it's pretty much exactly what you're trying to do.
http://railscasts.com/episodes/193-tableless-model

Related

How do I make error notices in this ruby form?

How can I make an error notice when somebody leaves spaces empty, etc...
I tried enumerous codes and they either didn't work or failed... I even installed a gem but nothing worked until now... please help with ideas/solutions
<div class="jumbotron"
<div class="container">
<h2>Signup</h2>
<%= form_for :user, url: '/users' do |f| %>
Número de Empregado: <br>
<%= f.number_field :NumeroEmpregado %><br>
Primeiro e Último Nome: <br>
<%= f.text_field :nome %><br>
Password: <br>
<%= f.password_field :password %><br>
Confirmação Password: <br>
<%= f.password_field :password_confirmation %><br>
<%= f.submit "Submit" %>
</div>
</div>
<% end %>
Controller:
class UsersController < ApplicationController
def new
end
def create
user = User.new(user_params)
if user.save
session[:user_id] = user.id
redirect_to '/'
else
flash[:error] = 'invalid value'
end
end
private
def user_params
params.require(:user).permit(:NumeroEmpregado, :nome, :password, :password_confirmation)
end
end
Rails only can validate when you submitted your form. In this case, you can check out this guide.
In other case, if you want immediately show validate message when user enter into input, you must validate it by using Javascript. You also can use Jquery validation plugin to do that.
Hope its help :)
you should use jquery validations if you want to check if the field is empty type validations before submit https://jqueryvalidation.org/documentation/ follow this link.
Or if you are ok with validating fields on submit then in create or update action of your controller you can check from the params if that field is empty. then you can show flash messages like this
flash[:notice] = 'valid value'
flash[:error] = 'invalid value'
Or you can add model level validations on that fields http://guides.rubyonrails.org/active_record_validations.html here
You can use the Active Record Validations.
If you have a model called User, then you can specify which attributes to validate for presence using the validates method and setting the presence to true, this will check if the field on the form has been filled, also if has only whitespaces.
For instance:
class User < ApplicationRecord
validates :nome, presence: true
...
For your controller:
def create
user = User.new(user_params)
if user.save
session[:user_id] = user.id
redirect_to '/'
else
flash[:error] = 'invalid value'
redirect_to new_user_path
end
end
Redirect to the new user path with flash[:error] as "invalid value".
For your view:
<% if flash[:error] %>
<div class="error">
<%= flash[:error] %>
</div>
<% end %>

Virtus: Replace accepts_nested_attributes (one-to-many) with a form object

Since more than a month I try to get behind the secrets of form objects in Rails 4.
Using virtus, I am already able to build very simple forms. However, I fail to develop a form object that replaces accepts_nested_attributes_for (in the model) and fields_for (in the form view).
In this question I explain a small phonebook-example: the form provides the possibility to enter a person's name and 3 phone numbers at once (find the whole code here).
Now I try to do the same with a form object. I get as far as this:
# forms/person_form_new.rb
class PersonFormNew
class PhoneFormNew
include Virtus
include ActiveModel::Model
attr_reader :phone
attribute :phone_number, String
end
include Virtus
include ActiveModel::Model
attr_reader :person
attribute :person_name, String
attribute :phone, PhoneFormNew
def persisted?
false
end
def save
if valid?
persist
true
else
false
end
end
private
def persist
#person = Person.create(name: person_name)
#person.phones.build(:phone)
end
end
# views/people/new.html.erb
<h1>New Person</h1>
<%= form_for #person_form, url: people_path do |f| %>
<p>
<%= f.label :person_name %> </ br>
<%= f.text_field :person_name %>
</p>
<p>
<%= f.fields_for :phone do |f_pho| %>
<%= f_pho.label :phone_number %> </ br>
<%= f_pho.text_field :phone_number %>
<% end %>
<p>
<%= f.submit %>
</p>
<% end %>
This gives me the error
undefined method `stringify_keys' for :phone:Symbol
line: #person.phones.build(:phone)
I fear however, this is not the only error.
Can you point me the way to realize a one-to-many assignment with a form object (preferable using Virtus)?
One solution is to create the associated object in a separate function on the form model. I was succussful by doing the following:
def persist!
#user.save!
#account.save!
create_admin_membership
end
def create_admin_membership
#membership = Membership.create! do |membership|
membership.user = #user
membership.account = #account
membership.admin = true
end
end
You can find an extended explanation here: http://w3facility.org/question/how-to-create-another-object-when-creating-a-devise-user-from-their-registration-form-in-rails/

How to implement form objects

Finally I was able to solve that issue
I try to implement a form object pattern in Ruby on Rails 4 and I just cannot find my mistake.
I constructed a sample application for a Phonebook, which includes the following models
Person
first_name
last_name
PhoneNumber
number
Email
address
[edit]
Thanks to #sockmonk I could solve one problem in this code. Still it is not working...
Here is the code I use
# app/models/person.rb
class Person < ActiveRecord::Base
has_many :phone_numbers
has_many :emails
end
# app/controllers/people_controller.rb
class PeopleController < ApplicationController
def new
#person_form = PersonForm.new
end
def create
#person_form = PersonForm.new(person_form_params)
#person_form.save
redirect_to person_path(#person)
end
def index
#people = Person.all
end
def show
#person= Person.find(params[:id])
end
private
def person_form_params
params.require(:person_form).permit(:person_first_name, :person_last_name, :phone_number_number, :email_address)
end
end
# app/forms/person_form.rb
class PersonForm
include Virtus
include ActiveModel::Model
# extend ActiveModel::Naming
# include ActiveModel::Conversion
# include ActiveModel::Validations
attr_reader :person
attr_reader :phone_number
attr_reader :email
attribute :person_first_name, String
attribute :person_last_name, String
attribute :phone_number_number, Integer
attribute :email_address, String
def persisted?
false
end
def save
if valid?
persist
true
else
false
end
end
private
def persist
#person = Person.create(first_name: person_first_name, last_name: person_last_name)
#phone_number = #person.phone_numbers.create(number: phone_number_number)
#email = #person.emails.create(address: email_address)
end
end
# app/views/people/new.html.erb
<h1>New Person</h1>
<%= form_for :person_form do |f| %>
<p>
<%= f.label :person_first_name %> </ br>
<%= f.text_field :person_first_name %>
<p>
<%= f.label :person_last_name %> </ br>
<%= f.text_field :person_last_name %>
<p>
<%= f.label :phone_number_number %> </ br>
<%= f.text_field :phone_number_number %>
<p>
<%= f.label :email_address %> </ br>
<%= f.text_field :email_address %>
<% end %>
(find the whole code at https://github.com/speendo/Phonebook2)
Btw. as you may have noticed, I use Virtus in this code - don't know if this is important.
If you need any additional information, please don't hesitate to let me know.
In your PersonForm class, you have these attributes:
attribute :person_first_name, String
attribute :person_last_name, String
But in your new.html.erb, you just reference :first_name and :last_name. You need to either change PersonForm to also use :first_name and :last_name, or change your template to use :person_first_name and :person_last_name.
The create method should redirect to #person_form.person instead.
try
def create
#person_form = PersonForm.new(person_form_params)
#person_form.save
redirect_to person_path(#person_form.person)
end

Rails getting form value to create method

I am creating a form which allows a User to send another User an email without actually seeing their email address.
I am using this gem: https://github.com/plataformatec/mail_form to handle this.
Currently I am very close to getting things working. I have my app emailing the correct person and giving the correct reply information. However, I cannot get the message body to appear.
My view form. (emails/new.html.erb)
<h1>Mail#new</h1>
<p>Find me in app/views/mail/new.html.erb</p>
<%= form_for #email do |f| %>
<%= f.label :message, 'Message:' %>
<%= f.text_area :message %>
<%= f.submit "Send Message" %>
<% end %>
my controller (emails_controller.rb)
class EmailsController < ApplicationController
def new
#email = Email.new
flash[:userid] = params[:id]
end
def create
#touser = User.find(flash[:userid])
#fromuser = User.find(current_user.id.to_i)
#email = Email.new(:name => #fromuser.name, :email => #fromuser.email, :message => params[:message], :to => #touser.email)
if #email.deliver
flash.now[:notice] = 'Thank you for your message!'
else
render :new
end
end
end
So using params[:message] does not work. How Can I access the :message data which I collect with my view?
if you are using form_for #email, the message will be in params[:email][:message]

Pass model between controllers and views in Ruby on Rails

I have signup form on my home screen. If user inputs invalid data I redirect him to /signin page. On this page I can see filled fields, but errors descriptions are empty.
Here is my UsersController:
class UsersController < ApplicationController
def new
#user = User.new(params[:user])
end
def create
#user = User.new(params[:user])
print #user
if #user.save
else
render 'new'
end
end
end
Method I use to show errors
module ApplicationHelper
def errors_for(model, attribute)
if model.errors[attribute].present?
content_tag :div, :class => 'well error' do
content_tag :ul do
model.errors[attribute].collect {|item| concat(content_tag(:li, item))}
end
end
end
end
end
My form partial:
<%= f.label :user_name %>
<%= f.text_field :user_name, :class=>"input-medium" %>
<%= errors_for(#user, :user_name) %>
<%= f.label :email %>
<%= f.text_field :email, :class=>"input-medium " %>
<%= errors_for(#user, :email) %>
<%= f.label :password %>
<%= f.password_field :password, :class=>"input-medium" %>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation, :class=>"input-medium" %>
and my signup view:
<section class="centered user-form-container">
<div class="user-form well pull-left">
<div class="centered">
<h1>Sign up</h1>
<%= form_for(#user, :action=>"create") do |f| %>
<%= render 'signup', :f=>f %>
<%= f.submit "Sign up" %>
<% end %>
</div>
</div>
</section>
In this situation, I believe you need to use flash.now, something like this:
Per the rails docs:
By default, adding values to the flash will make them available to the next request, but sometimes you may want to access those values in the same request. For example, if the create action fails to save a resource and you render the new template directly, that’s not going to result in a new request, but you may still want to display a message using the flash. To do this, you can use flash.now in the same way you use the normal flash:
def create
#user = User.new(params[:user])
print #user
if #user.save
else
# start with this, then expand the error text
flash.now[:error] = "Could not save user"
render 'new'
end
end
You would do this in your validation method.
If you are using a standard rails validation you would do this:
validates_presence_of :foo, :message => 'Message you want to display here'
If you are doing a custom validation then this:
def my_validation_method
begin
my_validation_code_here
rescue
self.errors[:base] << 'Message you want to display here'
end
end
def new
#user = User.new(params[:user])
if (!params[:user].nil?)
#user.valid?
end
end

Resources