ROR: What is causing uninitialized constant - ruby-on-rails

I had to update from Sendgrid V2 to V3. I am using the Sendgrid-ruby gem 5.3.
I am getting this error
NameError (uninitialized constant PasswordController::Email):
app/controllers/password_controller.rb:54:in `send_email'
May 06 08:57:01 burro-staging app/web.1: ArgumentError (wrong number of arguments (given 1, expected 0)):
Here is the line causing the issue (2nd line below).
mail = SendGrid::Mail.new
mail.from = Email.new(email: 'no-reply#getburro.com') <-----

Ruby is looking for Email class and couldn't find it. The reason is because Email belongs to Sendgrid module, and should be scoped like so:
Sendgrid::Email.new ...
as can be seen here:
https://github.com/sendgrid/sendgrid-ruby/blob/9dd0cf6c9eb7ecc1e4fe2824f9638468ab5fc818/lib/sendgrid/helpers/mail/email.rb
module SendGrid
class Email
attr_accessor :email, :name
def initialize(email: nil, name: nil)
...
And from the docs: https://github.com/sendgrid/sendgrid-ruby#with-mail-helper-class

Related

Getting wrong number of arguments calling a function with keyword arguments With Ruby 3.2

I updated the Ruby version from 2.7.3 to 3.2.0 in my project and some tests started to fail. Among those is one that is calling a function with keyword arguments. This is the error it's throwing:
1) NotificationsMailer notify Sets body
Failure/Error:
def notify(recipient_emails:, subject:, body:)
#body = body
#subject = subject
mail(bcc: recipient_emails, subject: #subject, reply_to: VENDOR_SUPPORT_EMAIL)
end
ArgumentError:
wrong number of arguments (given 1, expected 0; required keywords: recipient_emails, subject, body)
# ./app/mailers/notifications_mailer.rb:5:in `notify'
# /usr/local/bundle/gems/actiontext-6.1.6/lib/action_text/rendering.rb:20:in `with_renderer'
# /usr/local/bundle/gems/actiontext-6.1.6/lib/action_text/engine.rb:59:in `block (4 levels) in <class:Engine>'
# ./spec/mailers/notifications_mailer_spec.rb:16:in `block (3 levels) in <top (required)>'
This is the definition of the function being called:
class NotificationsMailer < ApplicationMailer
VENDOR_SUPPORT_EMAIL = "vendor-support#saatvamattress.com"
def notify(recipient_emails:, subject:, body:)
#body = body
#subject = subject
mail(bcc: recipient_emails, subject: #subject, reply_to: VENDOR_SUPPORT_EMAIL)
end
end
And this is the test file:
require "rails_helper"
RSpec.describe NotificationsMailer, type: :mailer do
describe 'notify' do
let(:recipient_emails) { %w[test#mail.com test2#mail.com] }
let(:mail) do
NotificationsMailer.notify(
recipient_emails: recipient_emails,
subject: 'subject',
body: 'body'
)
end
it 'Sets body' do
expect(mail.body.encoded).to match 'body'
end
it 'Sets subject' do
expect(mail.subject).to eq 'subject'
end
it "Does not set To" do
expect(mail.to).to be_nil
end
it "Does not set CC" do
expect(mail.cc).to be_nil
end
it "Sets BCC with recipients' emails" do
expect(mail.bcc).to eq ['test#mail.com', 'test2#mail.com']
end
it 'Sets reply_to with vendor support email' do
expect(mail.reply_to).to eq ['vendor-support#saatvamattress.com']
end
end
end
I know ruby 3 introduced some changes to keyword arguments, but as I'm calling the function with the arguments in the same order and specifying all the keywords, I don't see where my problem is.
Following some threads I tried sending the arguments in a hash and some other things that weren't so promising, but still getting the error, no clue of what's happening there.
I was able to reproduce your issue with Rails 6.1.7.2 and Ruby 3.2.1. The problem is that Rails 6.1 and Ruby 3.2 aren't fully compatible. There are efforts to backport 3.2 compatibility fixes to Rails 6.1 (see https://github.com/rails/rails/pull/46895) but they haven't been released yet it seems.
You could upgrade to a lower version of Ruby instead (3.1.2 worked fine for me, I'm sure 3.1.3 would too), or you could change your mailer code to be like this:
def notify(recipient_emails, subject, body)
[omitted]
end
(and obviously also change how you call that function).
There's some risk, though, that you'll run into more kwargs related issues with Rails 6.1 and Ruby 3.2, so maybe going with Ruby 3.1 is the better option.

FactoryBot: invalid factory with Ruby 3.0.3

Getting below error message when running Rspec after upgrading Ruby to 3.0.3
Failure/Error: FactoryBot.lint strategy: :build_stubbed
FactoryBot::InvalidFactoryError:
The following factories are invalid:
user - wrong number of arguments (given 1, expected 0; required keywords: event_type, object, summary, author) (ArgumentError)

Resque Mailer fails to send email due to wrong number of arguments

I'm a Rails newbie, so please forgive any ignorance on my part. The issue I'm having is that I have a Resque job setup to send an email. I have the job running, but it produces an error:
Unable to deliver email [send_daily_digest_email]: wrong number of arguments (given 2, expected 0)
I get this same error when I try to test the mailer from console...
TicketMailer.send_daily_digest_email("emailaddress#domain.com").deliver_now
Here is the mailer code:
class TicketMailer < ActionMailer::Base
layout 'mailer'
include Resque::Mailer
default :from => 'test <test#ignore.com>'
def send_daily_digest_email(email)
mail(:to => email, :subject => 'test')
end
end
What am I doing wrong? Where should I look to figure this out? Thanks!
As noted in the comments, the issue was due to Rails 5 not being fully supported in the current release of the resque-mailer gem. Support is built in now, but I had to pull from master on the repo:
gem "resque_mailer", :git => "https://github.com/zapnap/resque_mailer.git"

Mongodb error code 10068 or 17287 with rails 4.1 and devise

I'm trying to use mongoid with Rails 4.1.0 app and am getting error 17287 on moongodb 2.6.0 (same as 10068 on earlier versions of mongodb).
Here is the error message:
The operation: #<Moped::Protocol::Query #length=127 #request_id=5 #response_to=0 #op_code=2004 #flags=[] #full_collection_name="educandose_development.users" #skip=0 #limit=-1 #selector={"$query"=>{"_id"=>{"$oid"=>BSON::ObjectId('534d6f4f6372618443000000')}}, "$orderby"=>{:_id=>1}} #fields=nil> failed with error 17287: "Can't canonicalize query: BadValue unknown operator: $oid" See https://github.com/mongodb/mongo/blob/master/docs/errors.md for details about this error.
Any idea of what could be wrong?
After looking for a while, I realized that the new json cookies serializer on rails 4.1 breaks moped queries on devise resources.
To fix that, remove the following line on the cookies_serializer.rb initializer
Rails.application.config.action_dispatch.cookies_serializer = :json
You may want to get the old sessions_store.rb file back with content similar to:
YourApp::Application.config.session_store :cookie_store, key: '_yourapp_session'
or try the master branch of devise.
Take a look here: https://github.com/plataformatec/devise/issues/2949#issuecomment-40520236
and here: https://github.com/plataformatec/devise/pull/2882
Temporarily, until moped/session/json formatting is fixed, I'm using:
# app/models/concerns/zero_oid_fix.rb
module ZeroOidFix
extend ActiveSupport::Concern
module ClassMethods
def serialize_from_session(key, salt)
record = to_adapter.get((key[0]["$oid"] rescue nil))
record if record && record.authenticatable_salt == salt
end
end
end
And in devise model:
class User
devise :database_authenticatable, ...
# NOTE: Has to be after devise
include ZeroOidFix
...
end
Hope this answer will get obsolete fast.
Comment out the line below from the cookies_serializer.rb
Rails.application.config.action_dispatch.cookies_serializer = :json
Delete cookies.
Restart server.
Worked for me on "rails 4.1.4, devise 3.2.4, mongoid 4.0.0"

Rails 3: Duplicate validation error messages during testing

I'm getting some weird validation behavior: it's duplicating my validation error messages and I can't figure out what's causing it... it doesn't do this in the rails console.
Here is the validation from my Phone model:
# phone.rb
validates :number, :length => { :minimum => 3 }
My spec:
require 'spec_helper'
describe Phone do
it "requires a number" do
user = User.make!
#p = Phone.new(number:nil,user_id:user.id,type:2)
#p.valid?
puts #p.errors.inspect
#p.should have(1).error_on(:number)
end
My test results:
# rspec and machinist
#<ActiveModel::Errors:0x000000036f1258 #base=#<Phone id: nil, user_id: 614, kind: nil, number: nil, created_at: nil, updated_at: nil>, #messages={:number=>["is too short (minimum is 3 characters)", "is too short (minimum is 3 characters)"]}>
F
Failures:
1) Phone requires a number
Failure/Error: #p.should have(1).error_on(:number)
expected 1 error on :number, got 2
# ./spec/models/phone_spec.rb:11:in `block (2 levels) in <top (required)>'
Finished in 0.50988 seconds
1 example, 1 failure
As you can see, I'm getting "is too short (minimum is 3 characters)" twice... It's also /only/ happening during testing.
Any ideas?
Thanks!
The problem is in the line:
Dir["#{Rails.root}/app/**/*.rb"].each { |f| load f }
in the spec_helper.rb file, in the Spork.each_run block
If you change the method 'load' to 'require', it fixes the problem.
Or if you have a recent enough version of Spork, you can remove the line altogether.
I am pretty sure the error is caused when someone is installing a newer version Spork(0.9.0+) with old instructions, because the line:
Dir["#{Rails.root}/app/**/*.rb"].each { |f| load f }
doesn't even has to be stated explicitly in the spec_helper.rb file anymore. If it is then when the load method is used in the spec_helper.rb file, it reloads the files specified , most likely the cause of the strange RSpec duplicate validations errors.
I encountered a similar issue of duplicate error messages, but it seemed to stem from my use of a different directory structure than the standard, e.g.:
- app
\- models_one
|- models_two
|- models_three
My load/require call in the Spork.each_run block looked like this:
Dir["#{Rails.root}/app/models_*/*.rb"].each { |f| load f }
I removed this and replaced it with these:
ActiveSupport::Dependencies.clear
ActiveRecord::Base.instantiate_observers
And there were no more duplicate error messages.
I was helped by this post: http://adams.co.tt/blog/2012/04/12/duplicate-active-model-validation-errors/ in which the author says it's a 1.8.7-specific problem which involves requiring different paths which resolve to the same file, but I am using 1.9.3 so it may not be related.
I'm not sure if this is going to solve your problem, but rspec is very quirky if you don't follow rspec convention. Try some more idiomatic rspec like the following:
require 'spec_helper'
describe Phone do
context :validations do
let(:user) { double(:user) }
subject { Phone.new(number:nil,user_id:user.id,type:2) }
before do
subject.valid?
end
it 'should have a minimum length of 3' do
subject.should have(1).error_on(:number)
end
end
end
I'd also like to suggest that you shouldn't unit test Rails' built in validations; they are already tested in Rails itself. Specifically, your length validation is tested in activemodel/test/cases/validations/length_validation_test.rb. The behavior of the validations should be covered in your integration tests.
I hope that's helpful.
I'm having the same problem (using rspec & spork).
I suspect it's something to do with the model being required twice, causing validations to run twice.
If you explicity require 'phone' at the top of your spec, it seems to fix it.
But I'd really like to know what's causing the problem...

Resources