undefined method `before_action' for ActionMailer - ruby-on-rails-3

Trying to attach file to mail via before_action filter:
class UserMailer < ActionMailer::Base
before_action :add_logo_attachment
layout 'mail'
default from: "\"Admin\" <admin#site.com>",
to: Proc.new {Admin.pluck(:email)}
def send_mail
mail(subject: 'Hello, admin!')
end
.
.
private
def add_logo_attachment
attachments.inline['logo.png'] = File.read(Rails.root.join('app/assets/images/logo.png'))
end
end
And I get this error: undefined method `before_action' for UserMailer:Class
There is the same example in Rails guides and I can't understand what's the difference between my code and the code in guides.

There's no callbacks for ActionMaler::Base in Rails 3

Check the beginning of your controller. Had a similar error where this...
before_action :set_org, only: [:show, :edit, :update, :destroy]
got moved to above this accidently...
class OrgsController < ApplicationController
Move it back inside the class.

Try to
include AbstractController::Callbacks
in your mailer class and use before_filter
See this topic

Related

uninitialized constant ProfilesController

I have an error "uninitialized constant ProfilesController" on my Profiles controller. This is the profiles_controller.rb:
class ProfilesController < ApplicationController
def new
#profile = Profile.new
end
def create
#profile = Profile.new(params[:profile])
if #profile.save
redirect_to profile_path, notice: I18n.t('.profile.created')
else
render action: "new"
end
end
end
This is the routes.rb:
resources :profiles, only: [:new, :create]
And this the output of rake routes:
profiles POST /profiles(.:format) profiles#create
new_profile GET /profiles/new(.:format) profiles#new
When I click a link for "new_profile_path" I get the error, but to me everything seems OK? The controller name is plural,the routes are OK?
You most likely spelled your controller file wrong. Confirm that file is truly: `/app/controllers/profiles_controller.rb'
Really strange, I created a Books controller with a generator, renamed everything to Profiles and then it works as normal. As far as I can see the routes are identical. Strange....
I had the same problem when i checked the name of the controller was 'profile_controller.rb'(i had created it manually though). but inside the definition it was "ProfilesController".
class ProfilesController < ApplicationController
def index
end
def new
#profile = Profile.new
end
def create
end
end
So if your controller name is correct and you have added the route("resources :profiles") then it will work as expected

After initializer change 'alias_method' undefined method 'current_user' for class 'ApplicationController'

I've got the following initializer:
app/config/initializers/store_location.rb
module StoreLocation
def self.skip_store_location
[
Devise::SessionsController,
Devise::RegistrationsController,
Devise::PasswordsController
].each do |controller|
controller.skip_before_filter :store_location
end
end
self.skip_store_location
end
Relevant parts of my ApplicationController:
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :convert_legacy_cookies
before_filter :store_location
alias_method :devise_current_user, :current_user
def current_user
# do something
end
private
def store_location
# store location
end
Plus this in
config/environments/development.rb
Foo::Application.configure do
# normal rails stuff
config.to_prepare do
StoreLocation.skip_store_location
end
end
If I let RSpec/Rails run the self.skip_store_location I'm getting the following error:
/foo/app/controllers/application_controller.rb:7:in `alias_method': undefined method `current_user' for class `ApplicationController' (NameError)
If I remove the call, everything is back to normal (except the filter is run, as expected). I'm guessing that I mess up dependency loading somehow?
The problem is that you use alias_method before the method is defined in ApplicationController. To fix the problem, move the line
alias_method :devise_current_user, :current_user
below
def current_user
# do something
end
It's a bit misleading that the error appears when running skip_store_location. I assume that happens because skip_store_location loads several controllers, and one of them is a subclass of ApplicationController.

Rails 3.1, How to exclude authorize resource for devise controller?

I need to do some thing like that:
class ApplicationController < ActionController::Base
authorize_resource :unless => :devise_controller?
...
But, if I try to click on sign-up link, I get:
NameError in Devise::SessionsController#new
uninitialized constant Session
How can I skip authorize_resource for all the actions of devise_controller ? or any class that inherits devise_controller ?
What if there are many controllers to exclude ?
Any help will be more than appreciated, I don't need to pass an instance, just the class name
I do
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :authenticate_user!
# Don't let controllers get away with
# any monkey business
check_authorization :unless => :devise_controller?
end
and it works for me and I am using CANCAN with rails 3.2

How to invoke a rails sweeper in this scenario?

As you can see from code below. I am caching the show action. I also have the following method in the show action View.create_for(#song).
I would like to make it so, when View.create_for(#song) is called, it clears out the respective cache.
How would I go about this? Do I have to manually invoke the rails sweeper in the View model? If so, how?
My controller:
class SongsController < ApplicationController
caches_action :show, :cache_path => (proc do
song_path(params[:id], :user_id => user_signed_in? ? current_user.id : nil)
end)
# I tried with the following line, but this is not what I want. I only want to call the sweeper when `View.create_for(#song)` is called:
# cache_sweeper :views_sweeper, :only => [:show]
def show
#song = Song.find(params[:id])
View.create_for(#song)
end
end
My Sweeper:
class SongsSweeper < ActionController::Caching::Sweeper
observe Song
def after_save(song)
expire_fragment(/songs\/#{song.id}\/.*?/)
end
end
I think you should be referring to the songs_sweeper, not the views_sweeper:
cache_sweeper :songs_sweeper, :only => [:show]
I'm not sure of your requirements, but you could also be more specific in your SongsSweeper by changing after_save to after_create:
class SongsSweeper < ActionController::Caching::Sweeper
observe Song
def after_create(song)
expire_fragment(/songs\/#{song.id}\/.*?/)
end
end

Posting with Nested Resources

I have nested my resources (see below) and when I try to create a new entity, I get the following error. Does anyone know why I'm getting this error and how to solve it?
undefined method `applications' for nil:NilClass
resources careers do
resources applications
end
Within the 'Applications' controller I have:
before_filter [[:authenticate, :except => :new], :load_career]
def create
# The following line is where the error originates
#application = #career.applications.new(params[:application])
respond_to do |format|
...
end
end
private
def load_career
#career = Career.find(params[:career_id])
end
The Career and Application models have has_many :applications and belongs_to :career respectively.
And the '*_create_applications' migration has a career_id field.
I have never seen before_filters defined that way. I just tried it in Rails 3 and it doesn't seem to do anything. I would give each callback it's own before_filter call:
before_filter :authenticate, :except => :new
before_filter :load_career