Spork and aliased helper method in Rails application - ruby-on-rails

I have problem with Spork (v 1.0.0rc1) and Devise in my Rails application. I have this error when I run spork:
undefined method 'user_signed_in?' for class ApplicationController
In ApplicationController I have following lines:
alias logged_in? user_signed_in?
helper_method :logged_in?
When I remove these two lines, Spork works fine. I use logged_in? for historical reasons in views and I would like to continue to do so.
I have looked around and I couldn't find anything helpful.

Go back to "~> 0.9.0.rc" until they resolve it.

Related

The reason why it's possible to use helper method like current_user, authenticate_user!, and so on without including any module

The title is my question.
devise provide us many useful methods like current_user, authenticate_user!, and so on. I want to know why is it possible to use them without including any module like below.
class ApplicationController < ActionController::Base
before_action :authenticate_user!
end
Those method's definition is here
Somebody please help me!
The answer is devise included its helper methods into ActionController on behalf of you when Rails on_load
# devise/rails.rb
module Devise
class Engine < ::Rails::Engine
# ...
initializer "devise.url_helpers" do
Devise.include_helpers(Devise::Controllers)
end
# ...
end
# devise.rb
# ...
def self.include_helpers(scope)
ActiveSupport.on_load(:action_controller) do
include scope::Helpers if defined?(scope::Helpers)
include scope::UrlHelpers
end
ActiveSupport.on_load(:action_view) do
include scope::UrlHelpers
end
end
# ...
I saw many 3rd gems using on_load to include their methods (or themselves) into Rails core, maybe it's a typical way to do that (allows Rails to lazily load a lot of components and thus making the app boot faster). If you install some gems and you could use their methods on your model/controller/view then those gems did the same thing devise did above.
About those methods current_user, authenticate_user! ... they are dynamic methods devise will generate when it did include scope::Helpers into Rails (see code above and the link).
So one very good thing about rails is the fact that you get a lot of things for free out of the box. One of these things at the top level is autoloading.
So in the case of Devise. When you install Devise and run the generate command, you get a devise.rb file inside of your config/initializers/ folder. This file is always autoloaded by rails on server startup and reload. That's how all these methods are able to be use these devise methods without importing anything.
Read more at rails docs

How to find where is 'uninitialized constant' called in Rails?

I'm on Rails 6 and using devise and cancancan (and lots of other gems too).
When I call User.find(id).destroy! in rails console, it rollbacks with
NameError Exception: uninitialized constant User::Interactive
Also tried with byebug with the same result.
My head is spinning when I think about looking through all the files for the place where it is called.
I'd appreciate a clue how to track an uninitialized constant with less costs.
UPDATE
Already done by looking through gems.
UPDATE 2 - controller
class UsersController < ApplicationController
load_and_authorize_resource
#REST actions
end
The issue is that you are trying to call this in IRB, which doesn't load your application.
Try running it in the rails console instead ($ rails c)
so you should have controller like this.
class User::InteractiveController < ApplicationController
end

Cancancan in a engine

I want to use the rails gem cancancan in an engine (https://github.com/CanCanCommunity/cancancan). So I added it to my gemspec file like this:
s.add_dependency "cancancan"
In the engines dummy app and in a test app I load my engine and I'm getting always errors about undefined methods for every cancancan method.
undefined local variable or method `load_and_authorize_resource'
undefined local variable or method `can?'
[...]
This is my ability.rb file in the main app:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
can :manage, :all
end
end
I tried several solutions for using cancancan in engines but I found no solution for my engine. Here are some examples:
http://mx.kelsin.net/2011/08/10/using-cancan-in-a-engine-and-your-app/
https://github.com/CanCanCommunity/cancancan/wiki/Authorization-for-Namespaced-Controllers
https://github.com/CanCanCommunity/cancancan/wiki/Admin-Namespace
Where is my fault? Is one of the posted links really the solution or are they wrong/outdated? Is there a good tutorial to use cancancan in an engine? Thanks!
I could solve my problem by updating Cancancan from 1.9.2 to actual 1.10.1 and compare my engine with the one from this post: https://github.com/CanCanCommunity/cancancan/issues/151#issuecomment-69487040
you have load_and_authorize_resource in your WelcomeController, it's trying to load the Welcome model which doesn't exist. Instead, trying using authorize_resource class: false, so
class WelcomeController < ApplicationController
authorize_resource class: false
# rest of your code
end

How to include respond_to when you don't inherit from ApplicationController in Rails 4?

I have an API controller in a Rails 4.1.2 app that does not inherit from Application controller. I'm trying to include the respond_to method and get a method undefined error....So then I required actionpack at the top like below:
require 'action_pack'
class Api::V1::UsersController < Api::ApiController
version 1
doorkeeper_for :all
respond_to :json
def show
respond_with current_user.as_json(except: :password_digest)
end
end
and I still get
ActionController::RoutingError (undefined method `respond_to' for Api::V1::UsersController:Class):
But the respond_to method is part of the MODULE ActionController::MimeResponds::ClassMethods which can be found under the action_pack folder in a subdirectory if I open up the actionpack gem source code.
EDIT:
I should also mention Api::ApiController has a parent RocketPants::Base since I'm using the rocketpants api gem ... The gem's author states on his README: "RocketPants only includes the bare minimum to make apis. In the near future, it may be modified to work with ActionController::Base for the purposes of better compatibility with other gems."
I'm particularly interested in how to get access to the action_pack methods/libraries (if it's possible) in a standalone fashion, the way you can when you include activesupport.
Simply make your Api::ApiController (or its parent if there is one) inherit from ActionController::Base
Good thing you mention you are using RocketPants! A quick look at their github page confirm that it is already derivated from ActionController::Base. That renders my previous answer incorrect.
So it seems you don't need to call respond_to and that instead of respond_with you should use expose, but well it's a blink guess. You should follow their documentation
Also check your rails version. In Rails 4.2 and up, the respond_to syntax has been moved into the
responders gem.
Gemfile:
gem 'responders'
Console:
bundle install
rails g responders:install
I saw this error ActionController::RoutingError: undefined method 'respond_to' while I was using rails-api gem. After switching ActionController::API to ActionController::Base my error was resolved. This also fixed active_model_serializers failing to wrap render :json automatically with the corresponding serializers to my models. I may log this as an issue with the gem.
You have to include (at least) the ActionController::RespondWith module.

Calling an ApplicationController method from console in Rails

In Rails, supposing that the file is already loaded, how it is possible to call my_method from this example from console?
# some_file.rb
class MyClass < ApplicationController::Base
def my_method(args)
Another, very simple way to do this is to use an instance of ApplicationController itself.
ApplicationController < ActionController::Base
def example
"O HAI"
end
end
Then in the console, you can do the following:
>> ApplicationController.new.example
This will output the following:
O HAI
This, of course, has the restriction of not having access to everything a normal request would, such as the request object itself. If you need this, as the Patrick Klingemann suggested, you could use the debugger... I personally recommend using Pry:
Pry on RubyGems.org
RailsCast: Pry with Rails
This is likely much too late for you, but hopefully it will help someone in the future.
use debugger:
in your Gemfile add:
gem 'debugger'
then from the terminal:
> bundle
> rails s --debugger
in the controller action you're hitting:
class WidgetsController < ApplicationController
def index
debugger
#widgets = Widget.all
respond_with #widgets
end
end
then point your browser to: http://localhost:3000/widgets, the page will not finish loading. Return to the terminal where your server is running and you'll be in an interactive debugging session where you can run: my_method
It is not exactly the question asked, but you can also debug with the pry gem, similarly to debugger.
Add to the Gemfile:
gem "pry"
gem "pry-remote"
gem "pry-stack_explorer"
gem "pry-debugger"
In your method:
def myMethod
binding.pry
# some code
end
Done!
When you run your method, the page processing will freeze at binding.pry and pry will take over the prompt. Type n for each new step of the method, and play around with your variables that can be print (just typing them) in "real-time"!

Resources