I've set up Rails 4 ActionMailer to send me (as site admin) an email whenever a new user signs up (registrations#create - I'm using Devise).
Now I would like for current_user to be able to email the user whose profile they are currently viewing. So in users#show I'd like to have a form that simply generates an email :to #user.email, :from current_user.email (optionally override-able via text input), and possibly a body to the message.
A record of the message is not important. For this implementation I'm letting the users' inboxes handle all of the history. In fact I'd rather not store that data if it's possible to just pass it through the model/controller. If the addition of body text necessitates the use of a MessagesController then I would rather leave that out.
Many thanks.
<%= form_for(Message.new) do |f| %>
<div class="form-inputs">
<%= f.text)area :message %>
</div>
<%= f.hidden_field :sender_email, value: current_user.email %>
<%= f.hidden_field :receiver_email, value: #user.email %>
<div class="form-actions">
<button type="submit">Email</button>
</div>
<% end %>
Your message model will look like this
class Message
include ActiveModel::Model
def initialize(attributes = {})
attributes.each do |name, value|
send("#{name}=", value)
end
end
def persisted?
false
end
end
Message controller
class MessagesController < ApplicationController
def create
#message = Message.new(params.require(:message).permit(:sender_email, :receiver_email, :message))
if #message.valid?
MessageMailer.send_message(#message).deliver
redirect_to profile_url, notice: "Message sent"
else
render :new
end
end
end
class MessageMailer < ActionMailer::Base
def send_message(message)
#body = message.message
#from = message.sender_email
#to = message.receiver_email
mail to: #to, :subject => "new mail", :from => #from
end
end
The above code is not tested hope it works for your need
Related
I try to create a project page with a form to send invitation to other users. The Owner (who have created the project) can invite other users to participate to the project.
Right now, Here is the code :
views/projects/show.html.erb
<div class="container">
<h3> <%= #project.title %> </h3>
<h6> Créé par <%= link_to #project.owner.username, user_path(#project.owner) %> </h6>
<hr>
<h3> Inviter des utilisateurs au projet </h3>
<!-- form for search users -->
<%= form_tag new_invite_path, method: :post, :class => 'form-inline' do %>
<div class="form-group">
<%= text_field_tag :search, params[:search], size: 30, class: 'form-control' %>
</div>
<%= submit_tag 'Ajouter au projet', class: 'btn btn-success' %>
<% end %>
<!-- end form for search users -->
<!-- display users results -->
<% #users.each do |user| %>
<p> <%= user.username %> | <%= user.email %> </p>
<% end %>
<!-- end display results -->
</div>
controllers/projects_controller.rb
class ProjectsController < ApplicationController
def show
#project = Project.find(params[:id])
#users = User.search(params[:search])
end
def new
#project = Project.new
end
def create
#project = Project.new(project_params)
#project.owner = current_user
#project.members = []
if #project.save
puts #project
redirect_to user_path(current_user)
else
puts 'something went wrong'
puts #project.errors.full_messages
render 'new'
end
end
private
def project_params
params.require(:project).permit(:title, :description, :client, :deadline, :owner, :members)
end
end
On the project page, I have an Ajax form to find all the users, with their username and email.
Now, when I submit this form, I want to create an invitation (a notification, but I haven't begin the notification system). So, I have created this model :
class Invite
include Mongoid::Document
field :email
belongs_to :project
belongs_to :sender_id, :class_name => 'User'
belongs_to :recipient_id, :class_name => 'User'
end
And a controller :
class InvitesController < ApplicationController
def new
#invite = Invite.new(email: params[:search], sender_id: current_user.id)
byebug
#invite.save
end
def create
#invite = Invite.new(params[:search])
if #invite.save
flash[:success] = 'the invitation is send'
redirect_to user_path(current_user)
else
render 'projects/show'
end
end
end
So as you can see, I want to save the invite in my db (MongoDB -> Mongoid), but when I submit the form (on the project/show page), I have this error :
No route matches [POST] "/invites/new"
It's normal, but I want to know :
how to insert data in my database without rendering a view ?
how to have access to user ID with the email adresse ? (which is in the DB)
Thank you !
NB: don't hesitate to ask if you need more code to answer
1) You can insert the data on the database without rendering anything with this line on the controller render :nothing => true, :status => 200
so your create method will be like this
def create
#invite = Invite.new(params[:search])
if #invite.save
flash[:success] = 'the invitation is send'
render :nothing => true, :status => 200
else
render 'projects/show'
end
end
and this is wrong No route matches [POST] "/invites/new" when you try to create something, you will need to go to create, not the new action, just change the url on the form, because you are pointing to the wrong action.
2) If you have an User model and want to load an user by email, you can do something like this
User.find_by_email("the email of the user")
this is your model is User and the column where the email is, is named "email"
I have a nested resource placed in a nested form(for email input), and want to send emails using User Mailer. I am facing problems completing following challenges:
1) Have 10 input field generated by :fields_for on my invitation/new page in order to send up to 10 emails at a time.
2) After submission, cycle through the submitted emails and send an email to each of the submitted entries.
3) After emails have been sent, I have no use for the #invitation in the database and want to destroy it.
So far I have the following code:
The Models
class Scoreboard < ActiveRecord::Base
has_many :invitations
accepts_nested_attributes_for :invitations
end
class Invitation < ActiveRecord::Base
belongs_to :scoreboard
def send_invitation_email
UserMailer.send_invitation(self).deliver_now
end
end
The new.html.erb(invitations)
<%= form_for [#scoreboard, #invitation] do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.fields_for :invitations do |invites| %> <!-- this gives me one field. Need 10 fields to accept up to 10 emails -->
<div>
<%= invites.label :recipient_email %>
<%= invites.text_field :recipient_email %>
</div>
<% end %>
<%= f.submit "Send Invitation", class: "btn btn-primary" %>
<% end %>
The Invitations Controller
class InvitationsController < ApplicationController
def new
#scoreboard = Scoreboard.find(params[:scoreboard_id])
#invitation = #scoreboard.invitations.build
end
def create
#scoreboard = Scoreboard.find(params[:scoreboard_id])
#invitation = #scoreboard.invitations.build(invitation_params)
if #invitation.save
#invitation.send_invitation_email
flash[:success] = "Invitation sent successfully"
redirect_to new_scoreboard_invitation_path
else
render 'new'
end
end
private
def invitation_params
params.require(:invitation).permit(:recipient_email)
end
end
When I submit the form, in development log I get the following example code for the invitation:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"gS+olMC89noaYs0klYTg6IFgJ2cj4apML/NZbdbu2gia/KXjbPyyvSKrEUoj3rEAWxDknlgNmpnaefy7I6Hk3Q==", "invitation"=>{"invitations"=>{"recipient_email"=>"this#hotmail.com "}}, "commit"=>"Send Invitation", "scoreboard_id"=>"89"}
Using the logic that it's a possible collection of hashes within a hash, I came up with the following code in the User Mailer file:
user_mailer.rb
def send_invitation(invitation)
#invitation = invitation
#invitation.each do |key, value|
value.each do | x, y|
mail to: y , subject: "You have been invited"
end
end
end
Thanks in Advance!
Optional Bonus Question:
send_invitation.html.erb
<p>Hi View this Thanks </p> <br></br>
<%= # if someone could provide me a code to a link_to for the url for the scoreboard that the invitation is attached to that would be awesome %>
I want a logged in user to be able to input their friend's email into a form input, click send and it will send a mailer to them. Here is what I have so far
mailer.rb
class Mailer < ActionMailer::Base
default from: "donotreply#site.net"
def invite(recipient_email, body, subject)
#recipient_email = recipient_email
#body = body
mail(to: recipient_email,
body: body
subject: 'Join me on this awesome site!')
end
end
mailer_controller
class mailerController < ApplicationController
def new
end
def create
#recipient_email = params[:recipient_email]
body = params[:invitation]
Mailer.invitation(#recipient_email).deliver
flash.now[:notice] = 'Message sent'
redirect_to root_url
end
end
new.html.erb
<%= simple_form_for(new_invitation_url) do |f| %>
<%= f.label :email %>
<%= f.input :recipient_email %>
<%= f.submit :invite %>
<% end %>
invite.html.erb
Mailer#invite
Check out this awesome site!
<%= new_user_url %>
routes.rb
post "invites/new" => "invite#create", as: :new_invite
I want to have a form in my app where a logged in user can input their friend's email addresses, click send, and it will send out an automated email to the email addresses that they entered into the form. Here is what I have so far. I get unitialized constant when I click on the button to take you to the form so I don't know what else isn't working too.
invitations_controller.rb
class InvitationsController < ApplicationController
def new
#invitation = Invitation.new
end
def create
#invitation = Invitation.new(params[:invitation])
#invitation.invited_by = current_user.invitation_token # set the sender to the current user
if #invitation.save
Mailer.invitation(#invitation, new_user_path(:invite_token => #invitation.invited_by)).deliver #send the invite data to our mailer to deliver the email
else
flash.now[:notice] = "Something went wrong"
redirect_to root_url
end
end
end
mailer.rb
class Mailer < ActionMailer::Base
default from: "donotreply#mysite.com"
def invitation(invitation, signup_url)
subject 'Invitation'
recipients #recipient_email
from 'donotreply#mysite.com'
body :invitation => invitation, :signup_url => signup_url
invitation.update_attribute(:sent_at, Time.now)
end
end
invitation.html.erb
Mailer#invitation
You are invited to join our beta!
<%= signup_url(#invitation.invited_by) %>
new.html.erb (invitation form)
<%= simple_form_for #invitation, :url => new_invitation_path do |f| %>
<%= f.hidden_field :invitation_token, :value => #invitation.invited_by %>
<%= f.label :email %>
<%= f.email_field :email %>
<%= f.submit 'Send' %>
<% end %>
I can't even get to the invitation form because I get the uninitialized constant error. So for all I know it works beyond that. Help please
You need an Invitation model.
rails generate model Invitation invited_by:string sent_at:timestamp
See the getting started guide
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]