uninitialized constant ContactsController::ContactMailer - ruby-on-rails

I am trying to use ActiveModel to create a contact us form. When I click submit i get a NameError uninitialized constant ContactsController::ContactMailer on line ContactMailer.new_contact(#contact).deliver
Can someone show me what I am doing wrong?
Controller:
class ContactsController < ApplicationController
def new
#contact = Contact.new
end
def create
#contact = Contact.new(params[:contact])
if #contact.valid?
ContactMailer.new_contact(#contact).deliver
redirect_to root_path
else
render :new
end
end
end
Model:
class Contact
include ActiveModel::Model
attr_accessor :name, :email, :message
validates :name, presence: true
validates :email, presence: true
validates :message, presence: true, length: { maximum: 300 }
end
Form:
<h1>Contact Us</h1>
<%= form_for #contact do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :email %>
<%= f.email_field :email %>
<%= f.label :message %>
<%= f.text_area :message %>
<%= f.submit 'Submit' %>
<% end %>

Based on our comments, you have not implemented ContactMailer yet. You can do so at app/mailers/contact_mailer.rb.
You can find out more about mailers in the Rails docs.
(It sounds like you already know how to implement mailers, but you're not the only one who will ever read this answer.)

I too had the same problem because the contact_mailer.rb file wasn't matching with the class name that i had given to that file.
I renamed my file name i.e from contacts_mailer.rb to contact_mailer.rb for my class ContactMailer

Related

Send Email in a Rails App Without using a Database Model

I am relatively new to Rails. I have created a simple app, using Ruby 2.5 & Rails 5.2, that will send an email to an admin when a website visitor requests some information. The app does not use a database, because none of the visitor's information is to be saved or stored, therefore ActiveRecord is not used. Just need to get some information from the visitor via a form and email it. Research suggests using ActiveModel instead but I still can't get it to work. No 3rd party mailing apps needed. What am I overlooking? Model, Controller, Views, Mailer code appear below.
#Model: Visitor.rb
class Visitor
include ActiveModel::Model
include ActiveModel::Conversion
extend ActiveModel::Naming
include ActiveModel::Validations
attr_accessor :fname, :lname, :phone, :email, :interest
# Validations & Requirements
validates :fname, presence: true, length: { maximum: 50 }
validates :lname, presence: true, length: { maximum: 50 }
validates :lname, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 }, format: { with: VALID_EMAIL_REGEX }
validates :interest, presence: true
def initialize(fname, lname, phone, email, interest)
#fname = fname
#lname = lname
#phone = phone
#email = email
#interest = interest
post_initialize
end
# #make in lieu of #create
def self.make(fname, lname, phone, email, interest)
attributes = {fname: fname, lname: lname, phone: phone, email: email, interest: interest}
object = new(attributes)
object.save
#visitor = object
#visitor
end
def persisted?
false
end
def send_mail
# Following method defined in NotifierMailer
NotifierMailer.visitor_info(self).deliver_now
end
private
def post_initialize
if email
email.downcase
end
end
end
# Controller: Visitors_controller.rb
class VisitorsController < ApplicationController
def new
#Visitor = Visitor.new
end
def make
#visitor = Visitor.new(visitor_params)
if #visitor.valid?
#visitor.send_mail # Instance method in Guest model
flash[:notice] = "Your request has been sent! Thank you for contacting us."
redirect_to welcome_path
else
render 'new'
end
end
private
def visitor_params
params.require(:visitor).permit(:fname, :lname, :phone, :email, :interest)
end
end
# Routes: Routes.rb
Rails.application.routes.draw do
get 'favicon', to: 'pages#favicon'
root to: 'pages#index', as: 'welcome'
# ... other routes for static page navigation
get '/reqinfo', to: 'visitors#new'
post '/reqinfo', to: 'visitors#make'
end
# View: New.html.erb
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_with model: #visitor, url: reqinfo_path, local: true do |form| %>
<%= render 'layouts/error_messages', object: form.object %>
<%= form.label 'First Name' %>
<%= form.text_field :fname, class: 'form-control' %>
<%= form.label 'Last Name' %>
<%= form.text_field :lname, class: 'form-control' %>
<%= form.label :phone %>
<%= form.text_field :phone, class: 'form-control' %>
<%= form.label 'Email Address' %>
<%= form.text_field :email, class: 'form-control' %>
<%= form.label 'Interest' %>
<%= form.text_field :interest, class 'form-control' %>
<%= form.submit 'Submit', id: "button" %>
<% end %><!-- form_with -->
</div><!-- col-md6-3 -->
</div><!-- row -->
# Mailer: Notifier_mailer.rb
class NotifierMailer < ApplicationMailer
default from: 'noreply#thecompany.com'
def guest_info(visitor)
#visitor = visitor
mail(to: 'admin#thecompany.com', subject: "Website Visitors Request for Information")
end
end
# Message: Visitor_info.html.erb
<h1>Dear Admin;</h1>
<br>
<% timestamp = Time.now %>
<p>
<%= visitor.fname %> <%= #visitor.lname %> visited the TheCompany website on <%= timestamp.localtime %>. He/she is requesting information regarding a <%= #visitor.interest %>. Their contact information phone: <%= #visitor.phone %> and email: <%= #visitor.email %>
</p>

Rails update model wont work : No route matches, missing required keys: [:id]

I just started working on my second Rails project and am having some trouble with something that seems pretty basic. I am completely confounded though.
I've set up two models, User and Profile. A Profile belongs_to a User and the User has_one Profile.
I am setting up the edit form for a Profile right now and cannot get past this. The edit form loads correctly and inserts the data in the database but when I submit the form I get the following error
No route matches {:action=>"show", :controller=>"profiles", :format=>nil, :id=>#<Profile id: 7, user_id: 7, content: "Fill this in", created_at: "2015-01-08 19:08:22", updated_at: "2015-01-08 19:08:22", title: "fooobar", department: "one bar", school: "dsadsa", education: "two bar", academic_focus: "my bar is broken", website: "who bar is bokrbne">} missing required keys: [:id]
My models look like this
Class User < ActiveRecord::Base
has_one :profile, :class_name => 'Profile', :foreign_key => 'user_id'
attr_accessor :remember_token
end
class Profile < ActiveRecord::Base
belongs_to :user, :class_name => "User", :foreign_key => 'user_id'
attr_accessor :id
validates :content, presence: true, length: {maximum: 5000}
validates :user_id, presence: true
end
This is the form. I've tried various ways of adding a url: parameter to form_for but had no luck.
<%= form_for #profile do |f| %>
<%= f.label :title, class: 'col-lg-3 control-label' %>
<%= f.text_field :title, class: 'form-control' %>
<%= f.label :department, class: 'col-lg-3 control-label' %>
<%= f.text_field :department, class: 'form-control' %>
<%= f.label :school, class: 'col-lg-3 control-label' %>
<%= f.text_field :school, class: 'form-control' %>
<%= f.label :education, class: 'col-lg-3 control-label' %>
<%= f.text_field :education, class: 'form-control' %>
<%= f.label :academic_focus, class: 'col-lg-3 control-label' %>
<%= f.text_field :academic_focus, class: 'form-control' %>
<%= f.label :website, class: 'col-lg-3 control-label' %>
<div class="col-lg-8">
<%= f.text_field :website, class: 'form-control' %>
<%= f.hidden_field :id %>
<%= f.submit "Save changes", class: "btn btn-primary" %>
<% end %><!-- End of Form -->
Finally, here is the controller I am using.
class ProfilesController < ApplicationController
include ApplicationHelper
def index
# #profiles = Profile.limit(5)
#profiles = Profile.limit(15)
end
def show
#profile = Profile.find(params[:id])
end
def new
end
def create
#profile = Profile.new(profile_params)
if #profile.save
#successful save
flash[:success] = "Look at that. Ur Profile was ssaved"
redirect_to #profile
else
#unsuccesful
render 'new'
end
end
def edit
#user = current_user
#profile = Profile.find(#user.id)
end
def update
#profile = Profile.find(params[:id])
if #profile.update_attributes!(profile_params)
flash[:notice] = 'The User is successfully updated!'
redirect_to edit_profile_path
else
flash[:error] = #profile.errors.full_messages[0]
redirect_to edit_user_path
end
end
def view
#profile = Profile.find(params[:id])
end
private
def profile_params
params.require(:profile).permit(:id, :user_id, :content, :title, :department, :school, :education, :academic_focus, :website)
end
end
It is weird because I am using pretty much the exact same code I use for editing/creating users, but it isn't working. I figure it has something to do with relationship in the database.
Any insight would be much appreciated.
Thanks.
EDIT #1
Here's a photo of what happens when I submit the form
EDIT #2
If that image is too small here is a better one
http://i.imgur.com/Wu3v7Gu.png
EDIT #3
I changed the form_for arguments to
<%= form_for #profile, url: profile_update_path(#profile) do |f| %>
Now when the form is submitted I get this error
undefined method `profile_update_path' for #<#<Class:0x007fe1ae0e5618>:0x007fe1aca90458>
Remove the attr_accessor :id statement, it's likely interfering with the ActiveRecord default accessors in some way.

Rails Validation Failing for Create Action

So I'm trying to get my new/create actions working with form_for for my resource 'project' but the create form in 'new.html.erb' seems to think that the parameter 'version' is blank when I submit it, even though I am setting it equal to 1.
Projects Controller
def new
#project = current_user.projects.build if user_signed_in?
#project.version = 1
#project.unique_id = rand(1000000)
while(Project.find_by_unique_id(#project.unique_id) != nil)
#project.unique_id = rand(1000000)
end
end
def create
#project = current_user.projects.build(project_params)
if #project.save
flash[:success] = "Project created!"
redirect_to user_url(current_user.username)
else
render 'new'
end
end
private
def project_params
params.require(:project).permit(:description, :name, :media, :content_type, :file_size, :unique_id, :verison)
end
end
New.html.erb
<%= form_for(#project, html: {multipart: true}) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div>
<%= f.label :name %>
<%= f.text_field :name, maxlength: 50, class: 'form-control' %>
</div>
<div>
<%= f.label :description %>
<%= f.text_area :description, placeholder: "What is it all about?", class: 'form-control' %>
</div>
<%= f.file_field :media, accept: 'image/jpeg,image/gif,image/png,audio/mpeg,audio/vnd.wave' %>
<%= f.hidden_field :version %>
<%= f.hidden_field :unique_id %>
<%= f.submit "Create Project", class: "btn btn-primary" %>
<% end %>
Project Model
class Project < ActiveRecord::Base
belongs_to :user
has_many :comments, dependent: :destroy
validates :user_id, presence: true
validates :name, presence: true, length: { maximum: 50 }
validates :unique_id, presence: true
validates :version, presence: true
end
Thanks so much in advance!
I would set it equal to one in the form as a hidden field like this:
<div>
<%= f.hidden_field :version, value: 1 class: 'form-control' %>
</div>
I would also get rid of #project.version = 1 in your project new action.
Figured it out thanks to JTG. There appeared to be a typo in my strong params which was causing 'version' to be filtered out and thus not passed through.
Thanks everyone!

Allow customer too attach image to contact form

I have the below contact form and I would like to allow customers to send me an image as an attachment. I have added the field to the form but don't understand the following -
What migration do I create?
How do I attach the image to the
mailer?
View
<%= simple_form_for #inquiry, :method => :post do |f| %>
<%= f.input :spam, as: :hidden %>
<%= f.input :name %>
<%= f.input :phone %>
<%= f.input :email %>
<%= f.input :message %>
<%= f.file_field :image %> ## Attachment input here
<%= f.button :submit, 'Send' %>
<% end %>
Controller
def new
#inquiry = Inquiry.new
end
def create
redirect_to new_inquiry_path and return if params[:spam].present?
#inquiry = Inquiry.new(inquiry_params)
if #inquiry.valid?
InquiryMailer.admin(#inquiry).deliver
redirect_to inquiries_path
else
render :new
end
end
private
def inquiry_params
params.require(:inquiry).permit(:name, :email, :phone, :message)
end
Model
validates :name, presence: true
validates :email, presence: true
validates :phone, presence: true
validates :message, presence: true
inquiry_mailer.rb
class InquiryMailer < ActionMailer::Base
default from: "noreply#foo.com"
def admin(inquiry)
#inquiry = inquiry
mail to: "hello#foo.co.uk", subject: "Website Inquiry"
end
end
admin.text.erb
Website Inquiry
=========
Name: <%= #inquiry.name %>
Phone: <%= #inquiry.name %>
E-Mail: <%= #inquiry.email %>
Message: <%= #inquiry.message %>
You can make use of ActionMailer here
Ill provide an answer based upon your existing setup
You need to edit your mailer to look something like this
class InquiryMailer < ActionMailer::Base
default from: ENV['EMAIL_ADDRESS'] #I like to keep my email address hidden
def admin(inquiry)
#inquiry= inquiry
if inquiry.file
attachment_name = inquiry.file.original_filename
attachments[attachment_name] = inquiry.file.read
end
mail(to: ENV['EMAIL_ADDRESS'], subject: 'Website Inquiry')
end
end
You can keep admin.text.erb as it is and your controller stays the same
and within your form_for dont forget to add
<%= simple_form_for #inquiry, :method => :post, :multipart => true do |f| %>
so you the attachment can be added
Think thats it off the top of my head
Hope that helps, any questions then please ask

Simple_form has_and_belongs_to_many association is not updating

I have models for Venues and Photos:
class Venue < ActiveRecord::Base
has_and_belongs_to_many :photos
validates :name, presence: true
validates :permalink, presence: true, uniqueness: true
def to_param
permalink
end
end
class Photo < ActiveRecord::Base
mount_uploader :image, PhotoUploader
has_and_belongs_to_many :venues
end
I'm using simple_form to make the following form:
<div class="content-box">
<%= simple_form_for [:admin, #venue] do |f| %>
<%= f.input :name %>
<%= f.input :permalink %>
<%= f.input :description, input_html: { cols: 100, rows: 6 }%>
<%= f.input :address %>
<%= f.input :city %>
<%= f.input :phone %>
<%= f.association :photos %>
<%= f.button :submit, class: 'small radius' %>
<% end %>
</div>
And here is my controller for the Edit and Update methods:
class Admin::VenuesController < ApplicationController
def edit
#venue = Venue.find_by_permalink!(params[:id])
#photos = #venue.photos.all
end
def update
#venue = Venue.find_by_permalink!(params[:id])
if #venue.update_attributes(venue_params)
redirect_to edit_admin_venue_path(#venue), notice: 'Venue was successfully updated.'
else
render action: "edit"
end
end
private
def venue_params
params.require(:venue).permit(:name, :permalink, :description, :address, :city, :phone, :photo_ids)
end
end
The problem is that when I update using the form, all of the attributes for the venue model update fine, but the photo_ids are not updated or stored. I'm guessing it's something simple, but I'm not sure what it is. I'm using Rails 4, btw.
You need to permit photo_ids as an Array because photo_ids is passed as an Array upon form submission. Currently, photo_ids are not getting updated as you didn't permit them as an Array.
Update the venue_params as below:
def venue_params
params.require(:venue).permit(:name, :permalink, :description, :address, :city, :phone, :photo_ids => [])
end
Notice: :photo_ids => [] and NOT :photo_ids

Resources