Second Email is not sending in Devise Invitable for Rails 3 - ruby-on-rails

Hi I have a batch invitation module where a user can invite multiple users to register
And I am using devise_invitable gem
The problem is that, the first inputted email is being sent but for the second one, I am not receiving any email(s).
Here's my form:
.user-unit
%h2 Invite
= form_tag batch_invite_users_path, :method => :post do
= label_tag "Emails"
= text_field_tag :user_email_1
= text_field_tag :user_email_2
%br
= submit_tag "Send", class: 'btn-primary'
And my controller:
def batch_invite
if request.post?
valid_emails = []
#invalid_emails = []
#invited_emails = []
#invited_emails << params[:user_email_1] << params[:user_email_2]
#invited_emails.each do |email|
if email =~ Devise.email_regexp
user = User.invite!({:email => email}, current_user)
user.roles << Role.find(3)
valid_emails << email
else
#invalid_emails << email
end
end
if valid_emails.empty?
flash[:notice] = "No email have been sent."
else
redirect_to :back
flash[:notice] = "An invitation has been sent to #{valid_emails.join(',')}."
end
end
end
I have to fields, user_email_1 and user_email_2 and I converted those into an array so that I could loop it for the !invite method provided by the gem
user_email_1 is receiving an email but not the user_email_2
Here's my log/trace: http://pastebin.com/1kqvZXWC
Any workarounds will be appreciated.

Related

Rails - sending invitations to users that already exist

I have an invite method that sends users emails to be part of a team. I have a modal that displays some users that already have an account and a textfield to input more emails and sends an invite for the person to join the platform.
But if I type an email that already exists in the database I get:
Validation failed: Email has already been taken
But want to send an email even if the person already has an account.
Here's what I have:
def invite
invite = params.dig(:invite) || {}
candidate_ids = invite.dig(:candidate_ids) || []
extra_emails = invite.dig(:extra_emails) || ""
emails = extra_emails
.split(/,|;/)
.map(&:strip)
new_users = emails.map { |email| team_email_invite(email) }
candidate_ids.concat new_users.map(&:id)
invite_data = candidate_ids.map { |uid| {
:user_id => uid,
:team_id => #team.id,
} }
TeamInvite.create(invite_data)
.map!(&:email)
respond_to do |format|
format.html { redirect_to overviews_url, notice: 'Invites sent.' }
format.json { head :no_content }
end
end
def team_email_invite(email)
user = User.new({
:email => email,
:password => SecureRandom.hex,
:role => :shadow,
})
user.add_role :recruiter
user.skip_confirmation_notification!
user.save!
end
candidate_ids - It's the users that I display on the list(all good)
extra_emails - emails in the textfield
So when I write a user that already has an account in the textfield, team_email_invite tries to create a new user and crashes.
I don't want to do something like
begin
new_users = emails.map { |email| team_email_invite(email) }
rescue
new_users=[]
end
because then it doesn't send the invite.
Any idea how to solve this?
You could use first_or_initialize. The block only gets run if the User does not already exist. Here's an example...
user = User.where(email: email).first_or_initialize do |usr|
usr.email = email
usr.password = SecureRandom.hex
usr.role = :shadow
usr.skip_confirmation_notification!
end
user.add_role :recruiter
user.save!

NoMethodError undefined method `id' for nil:NilClass:

I know this kind of question is already answered multiple times but i seriously unable to figure it out what is causing a problem here, I am having trouble solving this problem. I keep getting the same error when i'm trying to create new registration ( http://localhost:3000/registrations/new?course_id=1 ) :
NoMethodError at /registrations
undefined method `id' for nil:NilClass
Here is my RegistrationsController:
class RegistrationsController < ApplicationController
before_action :set_registration, only: [:show, :edit, :update, :destroy]
def index
#registrations = Registration.all
end
def show
end
def new
#registration = Registration.new
#course = Course.new
#course = Course.find_by id: params["course_id"]
end
def create
#registration = Registration.new registration_params.merge(email: stripe_params["stripeEmail"], card_token: stripe_params["stripeToken"])
raise "Please Check Registration Errors" unless #registration.valid?
#registration.process_payment
#registration.save
redirect_to #registration, notice: 'Registration was successfully created.'
rescue Exception => e
flash[:error] = e.message
render :new
end
protect_from_forgery except: :webhook
def webhook
event = Stripe::Event.retrieve(params["id"])
case event.type
when "invoice.payment_succeeded" #renew subscription
Registration.find_by_customer_id(event.data.object.customer).renew
end
render status: :ok, json: "success"
end
private
def stripe_params
params.permit :stripeEmail, :stripeToken
end
def set_registration
#registration = Registration.find(params[:id])
end
def registration_params
params.require(:registration).permit(:course_id, :full_name, :company, :telephone, :email, :card_token)
end
end
My Registration Model:
class Registration < ActiveRecord::Base
belongs_to :course
def process_payment
customer_data = {email: email, card: card_token}.merge((course.plan.blank?)? {}: {plan: course.plan})
customer = Stripe::Customer.create customer_data
Stripe::Charge.create customer: customer.id,
amount: course.price * 100,
description: course.name,
currency: 'usd'
#Annotate Customer Id when Registration is Created
cusotmer_id = customer.id
end
def renew
update_attibute :end_date, Date.today + 1.month
end
end
Registration New.html.haml File :
%section#course-content
%section#ruby
%section.detailed-syllabus
.wrapper-inside
= form_for #registration, html: { class: "basic-grey" } do |f|
- if #registration.errors.any?
#error_explanation
%h2
= pluralize(#registration.errors.count, "error")
prohibited this registration from being saved:
%ul
- #registration.errors.full_messages.each do |message|
%li= message
.field
= f.hidden_field :course_id, value: #course.id
.field
= f.label :full_name
= f.text_field :full_name
.field
= f.label :company
= f.text_field :company
.field
= f.label :email
= f.text_field :email
.field
= f.label :telephone
= f.text_field :telephone
//‘Stripe.js’ will recognize the card data because we have marked the inputs with ‘data-stripe’ attribute as: number, cvv, exp-month and exp-year.
= javascript_include_tag "https://js.stripe.com/v2/"
:javascript
Stripe.setPublishableKey('#{Rails.application.secrets.stripe_publishable_key}');
= label_tag "Card Number", nil, required: true
.control-group
.controls
= text_field_tag :card_number, nil, class: "input-block-level", "data-stripe" => "number"
= label_tag "Card Verification", nil, required: true
.control-group
.controls
= text_field_tag :card_verification, nil, class: "input-block-level", "data-stripe" => "cvv"
= label_tag "Card Expires", nil, required: true
= select_tag :exp_month, options_for_select(Date::MONTHNAMES.compact.each_with_index.map { |name,i| ["#{i+1} - #{name}", i+1] }), include_blank: false, "data-stripe" => "exp-month", class: "span2"
= select_tag :exp_year, options_for_select((Date.today.year..(Date.today.year+10)).to_a), include_blank: false, "data-stripe" => "exp-year", class: "span1"
.actions
= f.submit "Registration Payment", class: "btn", style: "color: white;background: rgb(242, 118, 73);"
Does anyone know how to assist me in this? Greatly appreciate all the help.
Additional Can anyone please guide me through how to pass id between 2 models like this guy did between 2 models as he's creating a scaffold for one model but passing ID lets him create values for another model too without creating actions for another controller https://github.com/gotealeaf/stripe-basics.git
Edited:
GitHub Repository For This Code
https://github.com/ChiragArya/Stripe_CheckOut_Demo
From your comments, it appears the error is caused by :
#course.id being nil
The way to fix this is to ensure #course is defined properly. You need to do the following:
def new
#registration = Registration.new
#course = Course.find_by id: params["course_id"]
end
The other issue you have here is that your routes should be able to handle courses without having to append them with ?course_id=1:
#config/routes.rb
resources :registrations do
get :course_id, to: "registrations#new" #-> yoururl.com/registrations/:course_id
end
This will still give you the course_id param in the new action; just makes it more Rails.
--
Controller
You also need some structure in your code (you're aiming for fat model, thin controller). It looks like you're coming to Rails as a Ruby dev; you need to appreciate that Rails handles most of the exceptions etc for you.
Specifically, you need to look at how to remove code out of your actions:
def create
#registration = Registration.new registration_params
#registration.process_payment
if #registration.save
redirect_to #registration, notice: 'Registration was successfully created.'
else
# handle error here
end
end
private
def registration_params
params.require(:registration).permit(:course_id, :full_name, :company, :telephone, :email, :card_token).merge(email: stripe_params["stripeEmail"], card_token: stripe_params["stripeToken"])
end
-
`id' for nil:NilClass
Finally, you have to remember this error basically means the variable you're trying to invoke an action for is nil.
Ruby populates nil variables with a NilClass object, thus it's difficult to determine what the error actually is. All it means is that the variable you're trying to call a method on doesn't have the aforementioned method, as Ruby has populated it with the NilClass object.
Try changing Registration#new action to
def new
#course = Course.find(params[:course_id])
#registration = #course.registrations.new
end
add this in your def create
def create
#course = Course.find_by id: params["registration"]["course_id"]
#registration = Registration.new registration_params.merge(email: stripe_params["stripeEmail"], card_token: stripe_params["stripeToken"])
raise "Please Check Registration Errors" unless #registration.valid?
#registration.process_payment
#registration.save
redirect_to #registration, notice: 'Registration was successfully created.'
rescue Exception => e
flash[:error] = e.message
#course = Course.find_by id: params["registration"]["course_id"]
render :new
end

Mandrill API not sending

I'm trying to set up the Mandrill API to send an email when a user clicks a button, but I cannot seem to get it to send. The email will send perfectly fine from the console, so I know it is not a problem with the template (Devise emails also send find).
I think it is to do with how I have set it up in the controller but I cannot find any help on where I should put it instead.
Here is the code from the controller:
def attending
#event = Event.find(params[:id])
type = params[:type]
if type == "attending" && #event.space != 0
current_user.attending << #event
#event.space = #event.space - 1
#event.save
AdminMailer.new_attending(#event.user, current_user)
redirect_to :back, notice: "You've joined the group. Your number will be sent to #{#event.user.name}"
else type == "unattending"
current_user.attending.delete(#event)
redirect_to :back, notice: "You've removed yourself from the group"
end
end
Here is the admin_mailer.rb
class AdminMailer < ActionMailer::Base
require 'mandrill'
def mandrill_client
#mandrill_client ||= Mandrill::API.new MANDRILL_API_KEY
end
def new_attending(creator, user)
template_name = "new-attending"
template_content = []
message = {
to: [{email: creator.email, name: creator.name}],
subject: "Someone wants to go riding with you!",
merge_vars: [
{rcpt: creator.email,
vars: [
{name: "CREATOR_NAME", content: creator.name},
{name: "USER_NAME", content: user.name},
{name: "USER_NUMBER", content: user.number}
]}
]
}
mandrill_client.messages.send_template template_name, template_content, message
end
end
And here is the link they click in the view.html.erb that should send the email:
<td><% if event.user != current_user && event.space != 0 && user_signed_in? %>
<% unless event.attendees.include?(current_user) %>
<%= link_to "Join", attending_event_path(event, type: "attending"), class: "btn btn-primary btn-xs", method: :put %>
<% end %>
<% end %></td>
Any help in figuring out why it's not sending would be great! As I said, it works in the console when I type:
AdminMailer.new_attending(#event, #user)
Please replace following code.
AdminMailer.new_attending(#event.user, current_user)
with
AdminMailer.new_attending(#event.user, current_user).deliver
I hope this will work.

Submit Button runs the Create method, not Logon

We implemented a simple login method for our Ruby on Rails project, we have a button on the page to submit for the login information that the user will enter, but instead of pointing to our login method, the submit button runs our create method and tries to create another user.
def login
username = params[:username]
password = params[:password]
if(username == NIL || password == NIL)
loginfailed
else
comparisonUser = User.where("username = ?", username)
if(comparisonUser == NIL)
loginfailed
else
comparisonPassword = comparisonUser.password
if(comparisonPassword == password)
flash[:notice] = "Login Successful"
#user = comparisonUser
else
loginfailed
end
end
end
end
Here is the Create method:
def create
#user = User.create!(params[:user])
flash[:notice] = "User, #{#user.username} was successfully created."
redirect_to questions_path
end
and the code for the login button on the web page:
= form_tag users_path do
= label :userlogin, :username, 'Username'
= text_field :userlogin, :username
%br/
= label :userlogin, :password, 'Password'
= text_field :userlogin, :password
%br/
= submit_tag 'Login', :id => 'Login'
I probably need to add some more information to the submit_tag, but im not sure what to do.
Thanks for the help!
You're posting to the users_path, which is typically the create action (unless you've modified the route).
Instead of form_tag users_path you need to reference the appropriate route.

Mailer: Sending emails using Ruby on Rails failing

I have created a database of users in my Ruby on Rails app, and now I'm trying to create a mailer that send emails to all users in my database whenever I want.
Here's my model:
class MailMessage < ActionMailer::Base
def contact(recipient, subject, message)
# host = Hobo::Controller.request_host
# app_name = Hobo::Controller.app_name || host
#subject = subject
# #body = { :user => user, :host => host, :app_name => app_name }
#body["title"] = 'This is title'
#body["email"] = 'mark#doc.org.uk'
#body["message"] = message
#recipients = recipient
#from = 'no-reply#doc.org.uk'
#sent_on = Time.now
#headers = {}
end
end
Here's my controller:
class MailMessageController < ApplicationController
def sendmail
email = #params["email"]
recipient = email["recipient"]
subject = email["subject"]
message = email["message"]
MailMessage.deliver_contact(recipient, subject, message)
return if request.xhr?
render :text => 'Message sent successfully'
end
def index
render :file => 'app/views/mail_message/index.html'
end
end
Here's my views/mail_message:
<h1>Send Email</h1>
<%= form_tag :action => 'sendmail' %>
<p>
<label for="email_subject">Subject</label>
<%= text_field 'email', 'subject' %>
</p>
<p>
<label for="email_recipient">Recipient</label>
<%= text_field 'email', 'recipient' %>
</p>
<p>
<label for="email_message">Message</label>
<%= text_area 'email', 'message' %>
</p>
<%= submit_tag "Send" %>
<%= form_tag %>
Here's my enviroment.rb:
ActionMailer::Base.delivery_method = :sendmail
ActionMailer::Base.sendmail_settings = {
:location => '/usr/sbin/sendmail',
:arguments => '-i -t'
}
ActionMailer::Base.perform_deliveries = true # the "deliver_*" methods are available
ActionMailer::Base.raise_delivery_errors = true
ActionMailer::Base.default_charset = "utf-8"
ActionMailer::Base.default_content_type = "text/html" # default: "text/plain"
ActionMailer::Base.default_mime_version = "1.0"
ActionMailer::Base.default_implicit_parts_order = [ "text/html", "text/plain"]
When I run a test message, I get the following error:
You have a nil object when you didn't expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.[]
app/controllers/mail_message_controller.rb:4:in `sendmail'
It doesn't seem to recognise sendmail, but I have given its location. Any clues for how to fix this error will be very appreciated.
It looks like this line is the problem:
#params["email"]
If it's meant to be the data from the form, drop the #.
#params isint initialized in your controller.
You probably simple want to use params to get your http action parameters.

Resources