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
Related
I'm using nested attributes to user adresses.
class User < ApplicationRecord
accepts_nested_attributes_for :address, update_only: :true
I'm passing the address id as hidden field at sign-in.
<%= form_for (#user), :html => {:class => 'lead-form'} do |f| %>
<%= f.email_field :email, class:'form-control', placeholder: "Email", required: true %>
<%= f.password_field :password, class:'form-control', placeholder: "Senha", required: true %>
<%= f.fields_for :address do |addresses_form| %>
<%= addresses_form.hidden_field :address_id, :value => #address.id %>
<% end %>
<%= f.submit 'Pedir meu convite', class: "button lead-form-button" %>
<% end %>
The e-mail is validate as uniqueness. So, when somebody try to sign in with an already taken e-mail the address params are passed as nil and i get the error:
NoMethodError in Users#create
undefined method `id' for nil:NilClass
Any idea how can i fix that?
Here is my controller:
def new
#user = User.new
#address = #user.build_address
end
def create
#user = User.new(user_params)
if #user.save
log_in #user
flash[:success] = "Você está dentro. Esse é seu perfil! =) "
redirect_to #user
else
render 'new'
end
end
private
def user_params
params.require(:user).permit(:id, :primeiro_nome, :sobrenome, :email, :cpf, :telefone, :sexo, :data_de_nascimento, :password, address_attributes: [:id, :logradouro, :bairro, :cidade, :uf, :complemento, :cep])
end
ps: The association is one to one. How can i call the address attributes if i don't pass as hidden.
Address belongs to user? If yes, you just call #user.address
Maybe you should try using try method:
<%= addresses_form.hidden_field :address_id, :value => #address.try(: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.
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!
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
What is the proper way to have a form in a partial view reference an empty model in order to handle validation properly as defined on the model. Should I instantiate a new, empty model in the partial view and pass it through to the form? Here is what I'm working with...
MODEL
class NewsletterSignup < ActiveRecord::Base
def self.columns()
#columns ||= [];
end
def self.column(name, sql_type = nil, default = nil, null = false)
columns << ActiveRecord::ConnectionAdapters::Column.new(name, default, sql_type, null)
end
def persisted?
false
end
column :first_name, :string
column :last_name, :string
column :email, :string
column :zip, :string
validates :first_name, :last_name, :email, :zip, :presence => true
validates :email, :format => /^[-a-z0-9_+\.]+\#([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i
validates :zip, :format => /^\d{5}$/
end
Partial View
<%
signup = newsletter_signup.new
%>
<%= simple_form_for(signup, ...) do |f| %>
<%= f.input :first_name, :label => "First Name:" %>
<%= f.input :last_name, :label => "Last Name:" %>
<%= f.input :email, :label => "Email:" %>
<%= f.input :zip, :label => "Zip:" %>
...
<% end %>
But I can't seem to instantiate a new model like this. I assume I have to reference it in the view. (Note, I'm new to rails but have a decade+ of professional software development experience, so I apologize if some of rails constructs seem foreign to me and I may just be overlooking something simple!)
If your controller looks like this
def new
Model.new
end
def create
#model = Model.new(params[:model])
if #model.save
redirect root_path, notice: "Saved"
else
render action: 'new'
end
end
def edit
Model.find(params[:id])
end
def update
if #model.update(params[:model])
redirect root_path, notice: "Updated"
else
render action: 'edit'
end
end
You can have views like:
# new.html.erb
<%= render 'form' %>
# edit.html.erb
<%= render 'form' %>
# _form.html.erb
<%= form_for #model do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
...
<% end %>