I'm trying to send mail in a Rails 3 application using collectiveidea's delayed_job. If I try to send mail regularly (.deliver) it works fine, but as soon as I switch to delayed job, things fall to pieces.
The standard error I get in the delayed_job mysql table is:
{undefined method `name' for
nil:NilClass...
where 'name' is the first argument in the mailer's view (#contact.name). This works fine if I take delayed_job out again.
If I remove all references to #contact in the view, I get
{A sender (Return-Path, Sender or
From) required to send a message
In short, it doesn't seem to be understanding any arguments at all.
All relevant code below - if anyone has any suggestions for this it would be very appreciated
CONTROLLER
def sendmail
#contact = Contact.new(params[:contact])
if #contact.save
ContactMailer.delay.contact_mail(#contact)
flash[:notice] = 'Your message has been successfully sent'
redirect_to root_path
else
render :action => 'index'
end
end
MAILER:
class ContactMailer < ActionMailer::Base
default :from => "my#email.address"
def contact_mail(contact)
#contact = contact
mail(:to => 'my#email.address', :subject => 'Contact Form Query', :from => 'my#email.address', :content_type => 'text/plain')
end
handle_asynchronously :contact_mail, :run_at => Proc.new { 2.seconds.from_now }
end
MAILER VIEW:
You have received a new query:
-----------------------------------
<%= #contact.name %>
<%= #contact.business %>
<%= #contact.phone %>
-----------------------
<%= #contact.message %>
-----------------------
INITIALIZER:
Delayed::Worker.destroy_failed_jobs = false
Delayed::Worker.max_run_time = 5.weeks
And finally, the full error message:
{undefined method `name' for nil:NilClass
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/activesupport-3.0.0/lib/active_support/whiny_nil.rb:48:in `method_missing'
/Users/john/Websites/Rails/InDevelopment/connectted/app/views/contact_mailer/contact_mail.html.erb:4:in `_app_views_contact_mailer_contact_mail_html_erb___3386534441642202773_2166008980__4301703149293725172'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0/lib/action_view/template.rb:135:in `block in render'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/activesupport-3.0.0/lib/active_support/notifications.rb:54:in `instrument'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0/lib/action_view/template.rb:127:in `render'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0/lib/action_view/render/rendering.rb:59:in `block in _render_template'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/activesupport-3.0.0/lib/active_support/notifications.rb:52:in `block in instrument'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/activesupport-3.0.0/lib/active_support/notifications/instrumenter.rb:21:in `instrument'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/activesupport-3.0.0/lib/active_support/notifications.rb:52:in `instrument'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0/lib/action_view/render/rendering.rb:56:in `_render_template'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0/lib/action_view/render/rendering.rb:26:in `render'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0/lib/abstract_controller/rendering.rb:114:in `_render_template'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0/lib/abstract_controller/rendering.rb:108:in `render_to_body'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0/lib/abstract_controller/rendering.rb:101:in `render_to_string'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0/lib/abstract_controller/rendering.rb:92:in `render'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionmailer-3.0.0/lib/action_mailer/deprecated_api.rb:111:in `render'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionmailer-3.0.0/lib/action_mailer/old_api.rb:210:in `block in create_parts'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionmailer-3.0.0/lib/action_mailer/old_api.rb:208:in `each'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionmailer-3.0.0/lib/action_mailer/old_api.rb:208:in `create_parts'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionmailer-3.0.0/lib/action_mailer/deprecated_api.rb:143:in `create_parts'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionmailer-3.0.0/lib/action_mailer/old_api.rb:77:in `process'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionmailer-3.0.0/lib/action_mailer/base.rb:446:in `process'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionmailer-3.0.0/lib/action_mailer/base.rb:441:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionmailer-3.0.0/lib/action_mailer/base.rb:425:in `new'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionmailer-3.0.0/lib/action_mailer/base.rb:425:in `method_missing'
/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/performable_mailer.rb:6:in `perform'
/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/backend/base.rb:83:in `invoke_job'
/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/worker.rb:119:in `block (2 levels) in run'
/Users/john/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/timeout.rb:57:in `timeout'
/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed
/worker.rb:119:in `block in run'
/Users/john/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/benchmark.rb:309:in `realtime'
/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/worker.rb:118:in `run'
/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/worker.rb:176:in `reserve_and_run_one_job'
/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/worker.rb:103:in `block in work_off'
/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/worker.rb:102:in `times'
/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/worker.rb:102:in `work_off'
/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/worker.rb:77:in `block (2 levels) in start'
/Users/john/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/benchmark.rb:309:in `realtime'
/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/worker.rb:76:in `block in start'
/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/worker.rb:73:in `loop'
/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/worker.rb:73:in `start'
/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/command.rb:100:in `run'
/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/command.rb:79:in `block in run_process'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/daemons-1.1.0/lib/daemons/application.rb:250:in `call'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/daemons-1.1.0/lib/daemons/application.rb:250:in `block in start_proc'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/daemons-1.1.0/lib/daemons/daemonize.rb:199:in `call'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/daemons-1.1.0/lib/daemons/daemonize.rb:199:in `call_as_daemon'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/daemons-1.1.0/lib/daemons/application.rb:254:in `start_proc'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/daemons-1.1.0/lib/daemons/application.rb:294:in `start'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/daemons-1.1.0/lib/daemons/controller.rb:70:in `run'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/daemons-1.1.0/lib/daemons.rb:193:in `block in run_proc'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/daemons-1.1.0/lib/daemons/cmdline.rb:112:in `call'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/daemons-1.1.0/lib/daemons/cmdline.rb:112:in `catch_exceptions'
/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/daemons-1.1.0/lib/daemons.rb:192:in `run_proc'
/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/command.rb:78:in `run_process'
/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/command.rb:72:in `block in daemonize'
/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/command.rb:70:in `times'
/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/command.rb:70:in `daemonize'
script/delayed_job:5:in `<main>' |
The issue is with the code in your mailer taking the object instead of the objects id:
def contact_mail(contact)
#contact = contact
mail(:to => 'my#email.address', :subject => 'Contact Form Query', :from => 'my#email.address', :content_type => 'text/plain')
end
You should change that to this:
def contact_mail(contact_id)
#contact = Contact.find(contact_id)
mail(:to => 'my#email.address', :subject => 'Contact Form Query', :from => 'my#email.address', :content_type => 'text/plain')
end
Never pass the actual objects to your mailer. Simply pass the id's and retrieve them upon processing.
I had this same problem, and fixed it by moving all the attributes into instance variables. So, in the view:
<%= #contact.name %>
<%= #contact.business %>
<%= #contact.phone %>
becomes:
<%= #name %>
<%= #business %>
<%= #phone %>
and I just looked up the instance variables in the mailer method. So, in the mailer:
def contact_mail(contact)
#contact = contact
mail(:to => 'my#email.address', :subject => 'Contact Form Query', :from => 'my#email.address', :content_type => 'text/plain')
end
becomes:
def contact_mail(contact)
#name = contact.name
#business = contact.business
#phone = contact.phone
mail(:to => 'my#email.address', :subject => 'Contact Form Query', :from => 'my#email.address', :content_type => 'text/plain')
end
Why is it not working? Not sure, I imagine it has to do with some ActionMailer voodoo.
How to get it working? Abstract out the delayed job pieces into another class. Have the method that is delayed do nothing more than send them email; meaning that the rendering of the email is done in real time, but the sending of it is delayed. This should get around your problem and accomplish the asynchronous sending of emails.
Hey this might be far off, but you're not sending any params to your MAILER. Here's a copy of my referred_email.rb I keep in my lib/ dir. I call it with delayed_job:
#my controller
Delayed::Job.enqueue ReferredEmail.new(params[:subject], params[:editor1])
#Reffered_Email.rb
class ReferredEmail < Struct.new(:subject, :editor1)
def perform
(CardReferral.all.map(&:email) - CardSignup.all.map(&:email)).each do |cf|
#cf = CardReferral.find_by_email(cf)
Notifier.deliver_referred_magic_email(User.find(#cf.user_id), #cf.email, #cf.name, #cf.message, subject, editor1)
end
end
end
It seems like you are using both:
ContactMailer.delay.contact_mail(#contact)
and
handle_asynchronously :contact_mail, :run_at => Proc.new { 2.seconds.from_now }
which you should only do one or the other. Try removing the handle_asynchronously and see if that fixes the problem.
Related
My application has an User model that belongs_to :profile, :polymorphic => true. This profile can be Student, Manager, Enterprise or Employee and it needs to be approved, by its administrator, to log on the system. I used this approval approach.
I'm having a little troubles with the test part. It always outputs:
1) Error:
test_should_get_dashboard(ManagersControllerTest):
NoMethodError: undefined method `approved' for nil:NilClass
Probably relevant sources:
class User < ActiveRecord::Base
belongs_to :profile, :polymorphic => true
attr_accessible :approved
end
class ManagersControllerTest < ActionController::TestCase
include Devise::TestHelpers
fixtures :managers
fixtures :users
def setup
manager = Manager.create(:name => 'Manager', :cpf => '537.846.919-86')
#user = User.new(:email => 'user#user.com', :password => 'user#user.com')
#user.approved = true
#user.profile = manager
#user.save!
end
test "should get dashboard" do
sign_in #user
get :dashboard
assert_response :redirect
assert_redirected_to managers_root_path
end
end
class ManagersController < ApplicationController
def dashboard
p = Proc.new { |e| [e.name, e.id] if e.user.approved }
app_en = Enterprise.all.map(&p).compact.count
napp_en = Enterprise.count - app_en
app_em = Employee.all.map(&p).compact.count
napp_em = Employee.count - app_em
#app = [ app_en, app_em, 0 ]
#napp = [ napp_en, napp_em, 0 ]
#total = [ app_en + napp_en, app_em + napp_em, Student.count ]
tags_count = Activity.tag_counts.map(&:count)
#tags = Hash[Activity.tag_counts.map(&:name).zip(tags_count)]
#user = current_user
end
end
As I'm having troubles with the fixtures written, I'm ignoring them, but I would be very thankful if someone show a solution with fixtures. Even this way I'm getting stuck in this error. What should I do?
The Stack
/home/waldyr/Dropbox/Workspace/Rails/bancodevagas/app/controllers/managers_controller.rb:7:in `block in dashboard'
/home/waldyr/Dropbox/Workspace/Rails/bancodevagas/app/controllers/managers_controller.rb:8:in `map'
/home/waldyr/Dropbox/Workspace/Rails/bancodevagas/app/controllers/managers_controller.rb:8:in `dashboard'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/actionpack-3.2.6/lib/action_controller/metal/implicit_render.rb:4:in `send_action'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/actionpack-3.2.6/lib/abstract_controller/base.rb:167:in `process_action'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/actionpack-3.2.6/lib/action_controller/metal/rendering.rb:10:in `process_action'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/actionpack-3.2.6/lib/abstract_controller/callbacks.rb:18:in `block in process_action'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/activesupport-3.2.6/lib/active_support/callbacks.rb:425:in `_run__2212830968385571096__process_action__4077155092621945467__callbacks'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/activesupport-3.2.6/lib/active_support/callbacks.rb:405:in `__run_callback'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/activesupport-3.2.6/lib/active_support/callbacks.rb:385:in `_run_process_action_callbacks'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/activesupport-3.2.6/lib/active_support/callbacks.rb:81:in `run_callbacks'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/actionpack-3.2.6/lib/abstract_controller/callbacks.rb:17:in `process_action'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/actionpack-3.2.6/lib/action_controller/metal/rescue.rb:29:in `process_action'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/actionpack-3.2.6/lib/action_controller/metal/instrumentation.rb:30:in `block in process_action'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/activesupport-3.2.6/lib/active_support/notifications.rb:123:in `block in instrument'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/activesupport-3.2.6/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/activesupport-3.2.6/lib/active_support/notifications.rb:123:in `instrument'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/actionpack-3.2.6/lib/action_controller/metal/instrumentation.rb:29:in `process_action'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/actionpack-3.2.6/lib/action_controller/metal/params_wrapper.rb:206:in `process_action'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/activerecord-3.2.6/lib/active_record/railties/controller_runtime.rb:18:in `process_action'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/actionpack-3.2.6/lib/abstract_controller/base.rb:121:in `process'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/actionpack-3.2.6/lib/abstract_controller/rendering.rb:45:in `process'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/actionpack-3.2.6/lib/action_controller/metal/testing.rb:17:in `process_with_new_base_test'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/actionpack-3.2.6/lib/action_controller/test_case.rb:469:in `process'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/actionpack-3.2.6/lib/action_controller/test_case.rb:49:in `process'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/devise-2.1.2/lib/devise/test_helpers.rb:19:in `block in process'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/devise-2.1.2/lib/devise/test_helpers.rb:71:in `catch'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/devise-2.1.2/lib/devise/test_helpers.rb:71:in `_catch_warden'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/devise-2.1.2/lib/devise/test_helpers.rb:19:in `process'
/home/waldyr/.rvm/gems/ruby-1.9.2-p320/gems/actionpack-3.2.6/lib/action_controller/test_case.rb:386:in `get'
/home/waldyr/Dropbox/Workspace/Rails/bancodevagas/test/functional/manager_controller_test.rb:24:in `block in <class:ManagersControllerTest>'
The answer appears to be that not all the Enterprise or Employee models actually have an associated user. When using map to e.user.approved, the controller tries to pass .approved to user which can be nil in this case.
One simple solution is to change your Proc to be nil safe:
p = Proc.new { |e| [e.name, e.id] if e.user && e.user.approved }
Can anyone explain why I keep getting an error in production but not in development? Relevant parts:
get: /user/logout
ActionController::RoutingError (uninitialized constant User::SessionController):
activesupport/lib/active_support/inflector/methods.rb:229:in `block in constantize'
activesupport/lib/active_support/inflector/methods.rb:228:in `each'
activesupport/lib/active_support/inflector/methods.rb:228:in `constantize'
actionpack/lib/action_dispatch/routing/route_set.rb:69:in `controller_reference'
actionpack/lib/action_dispatch/routing/route_set.rb:54:in `controller'
actionpack/lib/action_dispatch/routing/route_set.rb:32:in `call'
journey/lib/journey/router.rb:68:in `block in call'
journey/lib/journey/router.rb:56:in `each'
journey/lib/journey/router.rb:56:in `call'
actionpack/lib/action_dispatch/routing /route_set.rb:600:in `call'
omniauth/lib/omniauth/strategy.rb:177:in `call!'
omniauth/lib/omniauth/strategy.rb:157:in `call'
omniauth/lib/omniauth/builder.rb:48:in `call'
airbrake/lib/airbrake/rack.rb:27:in `call'
Routes:
Application1::Application.routes.draw do
match('/auth/:provider/callback' => 'session#create', :format => false)
root(:to => 'blog/archives#index', :format => false)
namespace(:user) do
match('/logout' => 'session#destroy', :format => false)
end
namespace(:blog) do
match('/archive/:slug' => 'archive#show', :format => false)
constraints(:page => /page\d+/) do
match('/archives/:page' => 'archives#index', :format => false)
end
end
end
I am using Rails 3.2.3 with the latest Omniauth.
You have created a namespace user and therefore you should place the session controller that defines the destroy action in this path:
/app/controllers/user/session_controller.rb
Then you can do stuff like:
Create a file in /app/controller/user/base_controller.rb that defines this:
class User::BaseController < ApplicationController
# Whatever you want here
end
And define the sessions controller located in /app/controllers/user/session_controller.rb as:
class Users::SessionsController < User::BaseController
def destroy
# whatever you want destroy to do..
end
end
Read this for more documentation about namespaces and routing.
I'm following a clickatell tutorial and my code looks as follows. However I get the error
uninitialized constant ActionDispatch::Routing::Routes (NameError)
from /Library/Ruby/Gems/1.8/gems/actionpack-3.1.1/lib/action_dispatch/routing/route_set.rb:258:in `instance_exec'
from /Library/Ruby/Gems/1.8/gems/actionpack-3.1.1/lib/action_dispatch/routing/route_set.rb:258:in `eval_block'
from /Library/Ruby/Gems/1.8/gems/actionpack-3.1.1/lib/action_dispatch/routing/route_set.rb:235:in `draw'
from /Users/user1/Desktop/rails_projects/clickatellsms/config/routes.rb:1
from /Library/Ruby/Gems/1.8/gems/railties-3.1.1/lib/rails/application/routes_reloader.rb:29:in `load_paths'
from /Library/Ruby/Gems/1.8/gems/railties-3.1.1/lib/rails/application/routes_reloader.rb:29:in `each'
from /Library/Ruby/Gems/1.8/gems/railties-3.1.1/lib/rails/application/routes_reloader.rb:29:in `load_paths'
from /Library/Ruby/Gems/1.8/gems/railties-3.1.1/lib/rails/application/routes_reloader.rb:13:in `reload!'
from /Library/Ruby/Gems/1.8/gems/railties-3.1.1/lib/rails/application/routes_reloader.rb:7:in `initialize'
from /Library/Ruby/Gems/1.8/gems/activesupport-3.1.1/lib/active_support/file_update_checker.rb:32:in `call'
from /Library/Ruby/Gems/1.8/gems/activesupport-3.1.1/lib/active_support/file_update_checker.rb:32:in `execute_if_updated'
from /Library/Ruby/Gems/1.8/gems/railties-3.1.1/lib/rails/application/finisher.rb:63
from /Library/Ruby/Gems/1.8/gems/railties-3.1.1/lib/rails/application/finisher.rb:64:in `call'
from /Library/Ruby/Gems/1.8/gems/railties-3.1.1/lib/rails/application/finisher.rb:64
from /Library/Ruby/Gems/1.8/gems/railties-3.1.1/lib/rails/initializable.rb:30:in `instance_exec'
from /Library/Ruby/Gems/1.8/gems/railties-3.1.1/lib/rails/initializable.rb:30:in `run'
from /Library/Ruby/Gems/1.8/gems/railties-3.1.1/lib/rails/initializable.rb:55:in `run_initializers'
from /Library/Ruby/Gems/1.8/gems/railties-3.1.1/lib/rails/initializable.rb:54:in `each'
from /Library/Ruby/Gems/1.8/gems/railties-3.1.1/lib/rails/initializable.rb:54:in `run_initializers'
from /Library/Ruby/Gems/1.8/gems/railties-3.1.1/lib/rails/application.rb:96:in `initialize!'
from /Library/Ruby/Gems/1.8/gems/railties-3.1.1/lib/rails/railtie/configurable.rb:30:in `send'
from /Library/Ruby/Gems/1.8/gems/railties-3.1.1/lib/rails/railtie/configurable.rb:30:in `method_missing'
from /Users/user1/Desktop/rails_projects/clickatellsms/config/environment.rb:5
from /Users/user1/Desktop/rails_projects/clickatellsms/config.ru:4:in `require'
from /Users/user1/Desktop/rails_projects/clickatellsms/config.ru:4
from /Library/Ruby/Gems/1.8/gems/rack-1.3.4/lib/rack/builder.rb:51:in `instance_eval'
from /Library/Ruby/Gems/1.8/gems/rack-1.3.4/lib/rack/builder.rb:51:in `initialize'
from /Users/user1/Desktop/rails_projects/clickatellsms/config.ru:1:in `new'
from /Users/user1/Desktop/rails_projects/clickatellsms/config.ru:1
My code looks like this -
# controllers/sms.rb:
require 'clickatell'
class SMS
def initialize(config)
#config = config
end
def create(recipient, message_text)
api.send_message(recipient, message_text)
end
private
def api
#api ||= Clickatell::API.authenticate(
#config[:api_key],
#config[:username],
#config[:password])
end
end
# config/clickatell.yml:
api_key: 9999999
username: abcdefg
password: hijklmno
# config/environments/development.rb
CLICKATELL_CONFIG = YAML.load(File.open(File.join(RAILS_ROOT,
'config', 'clickatell.yml')))
# config/routes.rb:
ActionController::Routing::Routes.draw do |map|
map.resource :sms
end
# app/views/sms/new.html.erb:
<% form_tag '/sms', :method => :post do -%>
<label>Enter the recipients mobile number:</label>
<%= text_field_tag "recipient" %>
<label>Enter your message:</label>
<%= text_area_tag "message_text" %>
<%= submit_tag "Send SMS" %>
<% end %>
# controllers/sms_controller.rb:
class SmsController < ApplicationController
def create
sms = SMS.new(CLICKATELL_CONFIG)
sms.create(params[:recipient], params[:message_text])
flash[:notice] = "Message sent succesfully!"
redirect_to :back
rescue Clickatell::API::Error => e
flash[:error] = "Clickatell API error: #{e.message}"
redirect_to :back
end
end
That's your routes.rb which is non sense:
ActionController::Routing::Routes.draw do |map|
map.resource :sms
end
It should rather be:
APP_NAME_HERE_CAMEL_CASE_STYLE::Application.routes.draw do
resource :sms
end
Looks like you copy/pasted old Rails 2 code within a Rails 3 app.
I using sorcery for email activation and I've followed their wiki tutorial: https://github.com/NoamB/sorcery/wiki/User-Activation.
I'm pretty sure the problem lies within sending out emails and less so towards activation because that is another issue.
Here's the code for User Mailer:
class UserMailer < ActionMailer::Base
default :from => "my_gmail_account#gmail.com"
def activation_needed_email(user)
#user = user
#url = "http://0.0.0.0:3000/users/#{user.activation_token}/activate"
mail :to => user.email,
:subject => "Welcome to PolyHerd.com"
end
end
Here's my development.rb file:
SampleApp::Application.configure do
# Settings specified here will take precedence over those in config/application.rb
config.action_mailer.delivery_method = :smtp
ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.smtp_settings = {
:address => "smtp.gmail.com",
:port => "587",
:domain => "localhost:3000",
:enable_starttls_auto => true,
:authentication => "plain",
:user_name => "my_gmail_account#gmail.com",
:password => "my_pw"
}
I'm getting this when I run the code through console:
ruby-1.9.2-p180 :017 > UserMailer.activation_needed_email(u).deliver
ActionView::Template::Error: ActionView::Template::Error
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/activemodel-3.0.10/lib/active_model/attribute_methods.rb:392:in `method_missing'
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.0.10/lib/active_record/attribute_methods.rb:46:in `method_missing'
from /Users/x/sample_app/app/views/user_mailer/activation_needed_email.text.erb:1:in `_app_views_user_mailer_activation_needed_email_text_erb__925048320772673370_2171058260_3164940035285331741'
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/actionpack-3.0.10/lib/action_view/template.rb:135:in `block in render'
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/activesupport-3.0.10/lib/active_support/notifications.rb:54:in `instrument'
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/actionpack-3.0.10/lib/action_view/template.rb:127:in `render'
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/actionpack-3.0.10/lib/action_view/render/rendering.rb:59:in `block in _render_template'
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/activesupport-3.0.10/lib/active_support/notifications.rb:52:in `block in instrument'
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/activesupport-3.0.10/lib/active_support/notifications/instrumenter.rb:21:in `instrument'
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/activesupport-3.0.10/lib/active_support/notifications.rb:52:in `instrument'
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/actionpack-3.0.10/lib/action_view/render/rendering.rb:56:in `_render_template'
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/actionpack-3.0.10/lib/action_view/render/rendering.rb:26:in `render'
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/actionpack-3.0.10/lib/abstract_controller/rendering.rb:115:in `_render_template'
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/actionpack-3.0.10/lib/abstract_controller/rendering.rb:109:in `render_to_body'
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/actionpack-3.0.10/lib/abstract_controller/rendering.rb:102:in `render_to_string'
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/actionpack-3.0.10/lib/abstract_controller/rendering.rb:93:in `render'
... 7 levels...
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/actionmailer-3.0.10/lib/action_mailer/base.rb:673:in `mail'
from /Users/x/sample_app/app/mailers/user_mailer.rb:14:in `activation_needed_email'
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/actionpack-3.0.10/lib/abstract_controller/base.rb:150:in `process_action'
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/actionpack-3.0.10/lib/abstract_controller/base.rb:119:in `process'
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/actionpack-3.0.10/lib/abstract_controller/rendering.rb:41:in `process'
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/actionmailer-3.0.10/lib/action_mailer/old_api.rb:75:in `process'
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/actionmailer-3.0.10/lib/action_mailer/base.rb:471:in `process'
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/actionmailer-3.0.10/lib/action_mailer/base.rb:466:in `initialize'
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/actionmailer-3.0.10/lib/action_mailer/base.rb:450:in `new'
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/actionmailer-3.0.10/lib/action_mailer/base.rb:450:in `method_missing'
from (irb):17
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.0.10/lib/rails/commands/console.rb:44:in `start'
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.0.10/lib/rails/commands/console.rb:8:in `start'
from /Users/x/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.0.10/lib/rails/commands.rb:23:in `<top (required)>'
from script/rails:6:in `require'
EDIT:
Here's the email template:
Welcome to PolyHerd.com, <%= #user.username %>
===============================================
Congratulations, you are now a part of Poly Herd,
your username is: <%= #user.username %>.
To activate your account, just follow this link: <%= #url %>.
Thanks for joining and have a great day!
I was getting no error, however mails were not going out.
On looking at your domain, I got tempted to change mine. Am also in development mode. I changed it to localhost:3000, and mails are now coming through.
You guys rock!!!
Simon
New to rails, and I've just spent hours trying to hunt down a bug. Any help very appreciated.
I'm trying to make a rails page so that if a user enters /info/who_bought/1 the page outputs HTML, and if they enter /info/who_bought/1.xml, the page returns an XML file. (In short, I'm doing chapter 11 from the 'Agile Web Development with Rails' book)
The HTML-formatted output works fine, but if I enter the xml I consistently get a 'wrong number of arguments (1 for 0)' error page. Downloaded the actual ebook and did a direct copy/paste of all code; still facing the same problem. Google doesn't bring up any mention of code bugs.
Code & full stack trace below. If anyone has any ideas I'd be very appreciative. In short - what could possible cause xml.builder to return a '1 for 0 arguments' bug?
Many thanks,
Baggage
# app/controllers/info_controller.rb
class InfoController < ApplicationController
def who_bought
#product = Product.find(params[:id])
#orders = #product.orders
respond_to do |format|
format.html
format.xml {render :layout => false }
end
end
protected
def authorize
end
end
# app/views/info/who_bought.xml.builder
xml.order_list(:for_product => #product.title) do
for o in #orders
xml.order do
xml.name(o.name)
xml.email(o.email)
end
end
end
# app/models/product.rb
class Product < ActiveRecord::Base
has_many :orders, :through => :line_items
has_many :line_items
validates_presence_of :title, :description, :image_url
validates_numericality_of :price
validates_uniqueness_of :title
validates_length_of :title,
:minimum => 10
validates_format_of :image_url,
:with => %r{\.(gif|jpg|png)$}i,
:message => 'must be a URL for GIF, JPG ' +
'or PNG image.'
validate :price_must_be_at_least_a_cent
def price_must_be_at_least_a_cent
errors.add(:price, 'should be at least 0.01') if price.nil? || price < 0.01
end
def self.find_products_for_sale
find(:all, :order => "title")
end
end
# config/routes.rb
ActionController::Routing::Routes.draw do |map|
map.resources :users
map.resources :line_items
map.resources :orders
map.resources :products
map.connect ':controller/:action'
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
end
# Full trace
/usr/lib/ruby/1.8/builder/xmlbase.rb:134:in `to_xs'
/usr/lib/ruby/1.8/builder/xmlbase.rb:134:in `_escape'
/usr/lib/ruby/1.8/builder/xmlbase.rb:87:in `text!'
/usr/lib/ruby/1.8/builder/xmlbase.rb:144:in `_newline'
/usr/lib/ruby/1.8/builder/xmlbase.rb:60:in `method_missing'
app/views/info/who_bought.xml.builder:2
vendor/rails/activerecord/lib/active_record/associations/association_collection.rb:359:in `method_missing'
vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb:212:in `method_missing'
vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb:212:in `each'
vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb:212:in `send'
vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb:212:in `method_missing'
vendor/rails/activerecord/lib/active_record/associations/association_collection.rb:359:in `method_missing'
app/views/info/who_bought.xml.builder:1
vendor/rails/actionpack/lib/action_view/renderable.rb:39:in `send'
vendor/rails/actionpack/lib/action_view/renderable.rb:39:in `render'
vendor/rails/actionpack/lib/action_view/template.rb:73:in `render_template'
vendor/rails/actionpack/lib/action_view/base.rb:256:in `render'
vendor/rails/actionpack/lib/action_controller/base.rb:1177:in `render_for_file'
vendor/rails/actionpack/lib/action_controller/base.rb:940:in `render_without_benchmark'
vendor/rails/actionpack/lib/action_controller/benchmarking.rb:51:in `render'
vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:8:in `realtime'
vendor/rails/actionpack/lib/action_controller/benchmarking.rb:51:in `render'
app/controllers/info_controller.rb:6
vendor/rails/actionpack/lib/action_controller/mime_responds.rb:135:in `call'
vendor/rails/actionpack/lib/action_controller/mime_responds.rb:135
vendor/rails/actionpack/lib/action_controller/mime_responds.rb:164:in `call'
vendor/rails/actionpack/lib/action_controller/mime_responds.rb:164:in `respond'
vendor/rails/actionpack/lib/action_controller/mime_responds.rb:158:in `each'
vendor/rails/actionpack/lib/action_controller/mime_responds.rb:158:in `respond'
vendor/rails/actionpack/lib/action_controller/mime_responds.rb:107:in `respond_to'
app/controllers/info_controller.rb:5:in `who_bought'
vendor/rails/actionpack/lib/action_controller/base.rb:1256:in `send'
vendor/rails/actionpack/lib/action_controller/base.rb:1256:in `perform_action_without_filters'
vendor/rails/actionpack/lib/action_controller/filters.rb:617:in `call_filters'
vendor/rails/actionpack/lib/action_controller/filters.rb:610:in `perform_action_without_benchmark'
vendor/rails/actionpack/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'
/usr/lib/ruby/1.8/benchmark.rb:293:in `measure'
vendor/rails/actionpack/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'
vendor/rails/actionpack/lib/action_controller/rescue.rb:136:in `perform_action_without_caching'
vendor/rails/actionpack/lib/action_controller/caching/sql_cache.rb:13:in `perform_action'
vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:34:in `cache'
vendor/rails/activerecord/lib/active_record/query_cache.rb:8:in `cache'
vendor/rails/actionpack/lib/action_controller/caching/sql_cache.rb:12:in `perform_action'
vendor/rails/actionpack/lib/action_controller/base.rb:524:in `send'
vendor/rails/actionpack/lib/action_controller/base.rb:524:in `process_without_filters'
vendor/rails/actionpack/lib/action_controller/filters.rb:606:in `process_without_session_management_support'
vendor/rails/actionpack/lib/action_controller/session_management.rb:134:in `process'
vendor/rails/actionpack/lib/action_controller/base.rb:392:in `process'
vendor/rails/actionpack/lib/action_controller/dispatcher.rb:184:in `handle_request'
vendor/rails/actionpack/lib/action_controller/dispatcher.rb:112:in `dispatch_unlocked'
vendor/rails/actionpack/lib/action_controller/dispatcher.rb:125:in `dispatch'
vendor/rails/actionpack/lib/action_controller/dispatcher.rb:124:in `synchronize'
vendor/rails/actionpack/lib/action_controller/dispatcher.rb:124:in `dispatch'
vendor/rails/actionpack/lib/action_controller/dispatcher.rb:134:in `dispatch_cgi'
vendor/rails/actionpack/lib/action_controller/dispatcher.rb:41:in `dispatch'
/usr/lib/ruby/1.8/mongrel/rails.rb:76:in `process'
/usr/lib/ruby/1.8/mongrel/rails.rb:74:in `synchronize'
/usr/lib/ruby/1.8/mongrel/rails.rb:74:in `process'
/usr/lib/ruby/1.8/mongrel.rb:159:in `process_client'
/usr/lib/ruby/1.8/mongrel.rb:158:in `each'
/usr/lib/ruby/1.8/mongrel.rb:158:in `process_client'
/usr/lib/ruby/1.8/mongrel.rb:285:in `run'
/usr/lib/ruby/1.8/mongrel.rb:285:in `initialize'
/usr/lib/ruby/1.8/mongrel.rb:285:in `new'
/usr/lib/ruby/1.8/mongrel.rb:285:in `run'
/usr/lib/ruby/1.8/mongrel.rb:268:in `initialize'
/usr/lib/ruby/1.8/mongrel.rb:268:in `new'
/usr/lib/ruby/1.8/mongrel.rb:268:in `run'
/usr/lib/ruby/1.8/mongrel/configurator.rb:282:in `run'
/usr/lib/ruby/1.8/mongrel/configurator.rb:281:in `each'
/usr/lib/ruby/1.8/mongrel/configurator.rb:281:in `run'
/usr/bin/mongrel_rails:129:in `run'
/usr/lib/ruby/1.8/mongrel/command.rb:212:in `run'
/usr/bin/mongrel_rails:282
This is a conflict between Rails 3.1, Builder 3.0, and either the fast_xs gem or hpricot (which bundles fast_xs). The reason why some people can't reproduce it is that they don't have fast_xs or hpricot in their Gemfile.
Unfortunately, since it's a three-way conflict, everybody thinks it's the other library's fault:
Builder bug report
Rails pull request
fast_xs bug report
In the meantime, pile another monkey patch on the heap and add config/initializers/unbreak_string_to_xs.rb with the following:
class String
def fast_xs_absorb_args(*args); fast_xs; end
alias_method :to_xs, :fast_xs_absorb_args
end
(From this answer to a duplicate.)
Try (re)installing the 'builder' gem, that fixed the '1 for 0 arguments' bug for me :)
sudo gem install builder
Don't forget to restart your server afterwards
I would kind of like to blame the "for o in #orders" part. Perhaps trying with a traditional way would help to eliminate this suspicion:
#orders.each do |o|
...
end