I need to send the same message to three different e-mails.
How can I do this?
Something like using a for each?
This is working, but if I just add a field in my view, like:
<div class="form-group">
<%= label_tag(:to, "Recipient's email address") %>
<%= email_field_tag :to, "", class: "form-control" %>
</div>
I get the error:
400 bad request
because of the parameters.
My HTML is:
<h1>Send a message with Mailgun</h1>
<% flash.each do |key, value| %>
<div class="alert alert-success"><%= value %></div>
<% end %>
<%= form_tag(:action => 'create')%>
<div class="form-group">
<%= label_tag(:to, "Recipient's email address") %>
<%= email_field_tag :to, "", class: "form-control" %>
</div>
<div class="form-group">
<%= label_tag(:body, "Message") %>
<%= text_area_tag :body, "", class: "form-control" %>
</div>
<%= submit_tag("Send", :class => "btn btn-primary") %>
And my model:
class HomeController < ApplicationController
def index
end
def create
# Get message value from form
#message = params
# First, instantiate the Mailgun Client with your API key
mg_client = Mailgun::Client.new ('7a9c4084f-b0aacd0-a2b65624')
# Define your message parameters
html_output = render_to_string template: "notifier/send_email"
message_params = {:from => 'postmaster#sandbox671e4d0f627c.mailgun.org',
:to => #message[:to],
:subject => 'Mailgun message via API',
:text => #message[:body],
:html => html_output.to_str,
"o:tag" => 'test'}
# Send your message through the client
mg_client.send_message ('sandboxe6fb741ddb25.mailgun.org'), message_params
# Redirect on success
redirect_to root_path, notice: 'Message was sent.'
end
end
Related
been banging my head on the table over this one. I have another nested form but this one is driving me crazy.
The error is:
TypeError in CompaniesController#create
no implicit conversion of Symbol into Integer
#company = Company.new(company_params)
The controller:
class CompaniesController < ApplicationController
layout 'welcome'
def new
#company = Company.new
end
def create
#company = Company.new(company_params)
if #company.save
flash[:notice] = "New company created successful."
redirect_to admin_accounts_path
else
flash.now[:alert] = "Creation failed, please try again"
render :new
end
end
private
def company_params
params.require(:company).permit(:name, :location, :users_attributes => [:email, :password])
end
end
On the new.html.erb:
<%= render partial: 'form', locals: { company: #company, users_attributes: :users_attributes } %>
This code looks exactly like another nested setup I have, but it works :p
I had read that sometimes changing the params from => to just having a semicolon works, but replacing the user_attributes => with a user_attributes: didn't change anything.
EDIT: form.html.erb
<%= form_for company, url: companies_path do |f| %>
<div class="col-12">
<div class="row">
<div class="col p-0 mr-3">
<div class="form-group">
Company <%= f.label :name %>
<%= f.text_field :name, :placeholder => 'Company name', class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :location %>
<%= f.text_field :location, :placeholder => 'Location', class: 'form-control' %>
</div>
</div>
<div class="col p-0">
<%= f.fields_for users_attributes do |user_f| %>
<div class="form-group">
<%= user_f.label :email %>
<%= user_f.text_field :email, :placeholder => 'Your Email Address', class: 'form-control' %>
</div>
<div class="form-group">
<%= user_f.label :password %>
<%= user_f.password_field :password, :placeholder => 'Password', class: 'form-control' %>
</div>
<% end %>
</div>
<div class="col-12 p-0">
<%= f.submit "Sign-Up", :class => 'btn btn-primary btn-block btn-lg' %>
</div>
</div>
</div>
<% end %>
Use users instead of users_attributes on the form.
Don't forget to define accepts_nested_attributes_for :users in model Company
## new.html.erb
<%= render partial: 'form', locals: { company: #company, users_attributes: :users } %>
I wonder why you didn't put :users into the form directly
Here's my form code. After hitting send I'd like to see a confirmation message or redirect to a different page.
<%= flash[:notice]
<%= form_with(url: "/static_pages/thank_you") do |form| %>
<div class="row">
<div class="col-md-4">
<div class="form-group">
<%= form.label :name %>
<%= form.text_field :name, class: "form-control", placeholder: "Enter Name" %>
</div>
<div class="form-group">
<%= form.label :email, "Email Address" %>
<%= form.text_field :email, class: "form-control", placeholder: "Enter Email" %>
</div>
<div class="form-group">
<%= form.label :message %>
<%= form.text_area :message, class: "form-control", placeholder: "Enter Message" %>
</div>
</div>
</div>
<%= form.submit "Send" %>
<% end %>
Here is my controller code or at least the start of it. I'm suspecting I'm missing something on the page below.
class StaticPagesController < ApplicationController
def index
##products = Product.all
end
def landing_page
#products = Product.limit(4)
end
def contact
end
def about
end
def thank_you
#name = params[:name]
#email = params[:email]
#message = params[:message]
UserMailer.contact_form(#email, #name, #message).deliver_now
end
end
def thank_you
#name = params[:name]
#email = params[:email]
#message = params[:message]
UserMailer.contact_form(#email, #name, #message).deliver_now
flash[:notice] = "Mail sent successfully!"
redirect_to root_path
end
I'm working on a simple one-page contact form. Contact model have two attributes: phone and email. Email should be validated on backend (i did it in my model). But user can fill either email or phone in the contact form and send it. No Email field in necessary and i don't know how to make it optional.
contact.rb
class Contact < MailForm::Base
attribute :phone
attribute :email, :validate => /\A([\w\.%\+\-]+)#([\w\-]+\.)+([\w]{2,})\z/i,
presence: false
def headers
{
:subject => "My Contact Form",
:to => "email#admin.com",
:from => %("#{phone}" <#{email}>)
}
end
end
contacts_controller.rb
class ContactsController < ApplicationController
def new
#contact = Contact.new
end
def create
#contact = Contact.new(contact_params)
#contact.request = request
if #contact.deliver
flash.now[:notice] = 'Ваша заявка принята!'
render :new
else
flash.now[:notice] = 'Введите корректный email.'
render :new
end
end
private
def contact_params
params.require(:contact).permit(:phone, :email)
end
end
new.html.erb
<%= simple_form_for #contact, html: {class: 'form-inline'} do |f| %>
<div class="form-group">
<div class="col-sm-6">
<%= f.input_field :email, class: "form-control", placeholder: "email", required: false %>
</div>
</div>
<div class="form-group">
<div class="col-sm-6">
<%= f.input_field :phone, class: "form-control", placeholder: "+7 (095) 123-45-67" %>
</div>
</div>
<div class="form-group">
<div class="col-sm-6">
<%= f.button :submit, 'Submit', :class=> "btn btn-success" %>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<% flash.each do |key, value| %>
<div class="alert alert-info" role="alert">
<div class="alert alert-<%= key %>"><%= value %></div>
</div>
<% end %>
</div>
</div>
<% end %>
I'd probably go about it this way:
class Contact < MailForm::Base
attribute :phone
attribute :email, :validate => /\A([\w\.%\+\-]+)#([\w\-]+\.)+([\w]{2,})\z/i,
presence: false, allow_blank: true
validate :at_least_a_contact
def headers
{
:subject => "My Contact Form",
:to => "email#admin.com",
:from => %("#{phone}" <#{email}>)
}
end
private
def at_least_a_contact
unless phone.present? || email.present?
errors.add(:contact, "You need at least a contact method")
end
end
end
Use allow_blank: true in your validation in your model.
http://guides.rubyonrails.org/active_record_validations.html#allow-blank
I am saving an email to the database and then sending it. I am using the email model to validate the inputs, but I'm not sure how to display the error messages. I am getting an undefined method `errors' for nil:NilClass error for the fullmessage.errors.any? line in the index action(highlighted below)
View
<%= form_tag("/thank_you") do %>
<% if #fullmessage.errors.any? %> # <----- This line
<h3>Errors</h3>
<ul>
<% #fullmessage.errors.full_messages.each do |message| %> # Would also cause an error if exemption not already raised
<li><%= message %></li>
<% end %>
</ul>
<% end %>
<div class="row">
<div class="col-md-5">
<div class="form-group">
<%= text_field_tag :first_name, nil, class: 'form-control', placeholder: 'First Name' %>
</div>
</div>
<div class="col-md-7">
<div class="form-group">
<%= text_field_tag :last_name, nil, class: 'form-control', placeholder: 'Last Name' %>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<%= text_field_tag :email, nil, class: 'form-control', placeholder: 'Email Address' %>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="form-group text-area-wide">
<%= text_area_tag :message, nil, class: 'form-control text-area-wide', placeholder: 'When are you available?' %>
</div>
</div>
</div>
<%= submit_tag 'Get Started', class: 'btn btn-success' %>
<p>Skype required</p>
<% end %>
Controller
def thank_you
#first_name = params[:first_name]
#last_name = params[:last_name]
#email = params[:email]
#message = params[:message] || "Hello!"
#fullmessage = Email.create(first_name: #first_name, last_name: #last_name, email: #email, message: #message)
if #fullmessage.valid?
ActionMailer::Base.mail(
:from => #email,
:to => 'erikvdw#comcast.net',
:subject => "A new contact form message from #{#first_name} #{#last_name}",
:body => #message).deliver
else
redirect_to root_path
flash[:alert] = 'There was an issue with your submission'
end
end
Model
class Email < ActiveRecord::Base
validates_length_of :first_name, :maximum => 25, :minimum => 2
validates_length_of :first_name, :maximum => 30, :minimum => 2
validates_format_of :email, :with => /\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
validates_length_of :message, :maximum => 500, :minimum => 20
end
You have two options:
Use render instead of redirect to (this way you'll keep your #fullmessage object.
Save error into flash[:alert] and display it in the view
The 2nd option is more universal, you could add the relevant code to the layout and use it across the whole site. E.g.:
<% if !flash.empty? %>
<div id="flash">
<% flash.keys.each do |k| %>
<div class="alert alert-<%= k %>">
<%= flash[k] %>
</div>
<% end %>
</div>
<% end %>
Nil class means that the #fullmessage is nil and hasn't been set, and nil does not have the method errors, hence the error.
When you redirect, the #fullmessage value will have nothing because http is stateless. Absent caching and cookies, every variable is recreated with every request. think what you are trying to do is display the flash messages, if that is the case you can add the #fullmessage.errors to the flash and be able to display that on the redirect.
Firstly, I would like to describe what I am going to do. So, my application is set of tasks (eg. exercises depend on writing computer program) which user it available to send solutions through form and server will have compiled it and return results of process.
My problem is that I have model Solution which is presented below:
Solution(id: integer, exercise_id: integer, code: string, user_id: integer,
created_at: datetime, updated_at: datetime, language_id: integer)
and exercise_id, user_id, language_id are foreign keys and postgresql return error that it couldn't be null values...
The form which I use to send this information looks like below:
<fieldset style="add">
<legend>Send solution</legend>
<%= form_for [#user, #exercise, #solution], url: exercise_solutions_path, :html => { role: "form" } do |f| %>
<div class="form-group">
<%= f.label "Source code" %>
<br>
<%= f.text_area :code %>
</div>
<div class="form-group">
<%= f.label "Programming language" %>
<br>
<%= f.select(:language_id, available_lang) %>
</div>
<div class="form-group">
<%= f.submit "Send", :class => "btn btn-default" %>
</div>
<% end %>
</fieldset>
Frankly speaking I don't how to include more information such as user.id or exercise.id. Params look like:
#_params
{"utf8"=>"✓", "authenticity_token"=>"abwhTn3KrVneli0pCVccoWHyzlI7cRTFK5Wo7DdYRK+lL4GwZ8jUPqdzn8ZznCHsWTkfDAFS2RP6gTkWuk33iw==", "solution"=>{"code"=>"ds", "language_id"=>"C++"}, "commit"=>"Wyślij", "controller"=>"solutions", "action"=>"create", "exercise_id"=>"1"}
SolutionController
class SolutionsController < ApplicationController
def index
#solutions = Solution.last(20)
end
def new
#solution = Solution.new
end
def create
#solution = Solution.new(solution_params)
if #solution.save
redirect_to #solution
else
render :new
end
end
def edit
#solution = Solution.find(params[:id])
if #solution.update(solution_params)
redirect_to #solution
else
render :edit
end
end
def destroy
end
private
def solution_params
params.require(:solution).permit(:language_id, :code)
end
end
Edit:
<fieldset style="add">
<legend>Send solution</legend>
<%= form_for [#user, #exercise, #solution], url: exercise_solutions_path, :html => { role: "form" } do |f| %>
<div class="form-group">
<%= f.label "Source code" %>
<br>
<%= f.text_area :code %>
</div>
<div class="form-group">
<%= f.label "Programming language" %>
<br>
<%= f.select(:language_id, available_lang) %>
</div>
<div class="form-group">
<%= f.hidden_field :exercise_id, value: #exercise.id %>
<%= f.hidden_field :user_id, value: #user.id %>
<%= f.submit "Send", :class => "btn btn-default" %>
</div>
<% end %>
</fieldset>
You could 1) add hidden_fields in your form to set the missing attributes:
<div class="form-group">
<%= f.hidden_field :exercise_id, value: #exercise.id %>
<%= f.hidden_field :user_id, value: #user.id %>
<%= f.submit "Send", :class => "btn btn-default" %>
</div>
Make sure to add these attributes to the solution_params permitted parameters:
def solution_params
params.require(:solution).permit(:language_id, :code, :exercise_id, :user_id)
end
A better idea would be to manually set the exercise and user in the controller and leave your solution_params as is. That way you're not allowing the exercise and user to be set by mass assignment, which could be spoofed.
So instead do 2) in your controller:
def create
#solution = Solution.new(solution_params)
#solution.exercise_id = params[:exercise_id]
#solution.user_id = params[:user_id]
if #solution.save
redirect_to #solution
else
render :new
end
end
I'm assuming that :exercise_id and :user_id are in the URL. If not add them as hidden_fields as needed (but this time not on the form object):
<%= hidden_field_tag :user_id, #user.id %>
Also remember to actually select a language_id from the dropdown before you submit the form.