Calling an ApplicationController method from console in Rails - ruby-on-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"!

Related

Rails 4 + append_view_path

I want to use dynamic path in my controller in rails gem.
I've added to
module MyGem
class FooController < Config.controller
before_action ->{ append_view_path "app/views/my_gem/#{wizard_name}" }
...
and in views I need to specify path like
app/views/my_gem/#{wizard_name}/my_gem/foo/some.erb
is in Rails some way, to cut the relative path of gem namespace, and get lookup path like?
app/views/my_gem/#{wizard_name}/some.erb
# or
foo/bar/some.erb
Thank you!
UPD:
I understand, that there is way with disabling isolate_namespace in Engine, but I believe, that it is not best and only option.
UPD2: For Rails4 this idea was very useful https://coderwall.com/p/p_yelg/render-view-outside-of-a-controller-in-rails-4
The Devise gem has a way of adding views lookup path by overriding the _prefixes method:
class DeviseController < Devise.parent_controller.constantize
include Devise::Controllers::ScopedViews
# Override prefixes to consider the scoped view.
# Notice we need to check for the request due to a bug in
# Action Controller tests that forces _prefixes to be
# loaded before even having a request object.
#
# This method should be public as it is is in ActionPack
# itself. Changing its visibility may break other gems.
def _prefixes #:nodoc:
#_prefixes ||= if self.class.scoped_views? && request && devise_mapping
["#{devise_mapping.scoped_path}/#{controller_name}"] + super
else
super
end
end
end
Can this be applied to your use case?
See source:
https://github.com/plataformatec/devise/blob/master/app/controllers/devise_controller.rb
Usually, you should only override the partial views or the functions from that gem, do not load from the gem lib like this, because when deploying to the real server it will raise many troubles for you to debug and improve.
You could make your how render method that reads an arbitrary file, interpret the ERB and render it as an HTML page for instance.
ERB.new(File.read(Rails.root.join('foo', bar', 'some.erb'))).result(binding)
By passing binding, the template will have access to the all the variables in the current context.
See ERB docs for more details: http://apidock.com/ruby/ERB
Assuming your gem is an engine, you should be able to simply call render :some in the engine. If the app has a view called <gem_name>/<controller_name>/some.html.erb it will be used.
Also, you can provide a version of that view in your gem that will be used if the app does not yet provide one.
If you need the wizard_name to also be looked up, I think the best way to do that would be to move that portion of the view path to the to the end where you are calling render.
So in your gem's controller you would write render "#{wizard_name}/some" and it would look for that view both in our app's app/views/<gem_name>/<controller_name>/<wizard_name>/some.html.erb and in your gem's app/views/<controller_name>/<wizard_name>/some.html.erb.

Rails: where does the #controller come from?

I am working on an old plugin "menu_helper" (legacy code uses it).
https://github.com/pluginaweek/menu_helper
The main entrance of this library is as follows,
module PluginAWeek
module MenuHelper
def menu_bar(options = {}, html_options = {}, &block)
puts #controller.class
MenuBar.new(#controller, options, html_options, &block).html
end
end
end
ActionController::Base.class_eval do
helper PluginAWeek::MenuHelper
end
The code works in rails 2.3.5 without problem but fails in 4.2.6.
When I puts #controller.class, in 2.3.5, it will always return the current controller that is using this library, but in 4.2.6 it will be NillClass.
So where does this #controller come from? How do I modify in 4.2.6 to make it work.
Note 1: to use this, I just need to call
html = menu_bar(options,:id => 'menuid')
No any controller is passed in.
Note 2: I am currently running it on controller test.
Thanks.
First of all, I would not use a gem that has not been maintained in the past 5 years and that the master build is currently failing. I'd try to find a well-maintained alternative or if the gem is small enough, to redo it myself.
This being said, menu_helper seems to use this variable: https://github.com/pluginaweek/menu_helper/blob/master/lib/menu_helper/menu.rb#L51
If you want to make it work, do a before_action that would instantiate this variable with the current controller:
before_action :set_legacy_controller
def set_legacy_controller
#controller = controller
end

Access a methods content without executing it in Ruby

This question has been keeping me busy for some time now, so I hope someone has an idea on how to tackle this.
Lets take a simple Class with a method (simplified without an initialize method):
class MyClass
def my_method
page.search('//p')
end
end
Now, is there a way to retrieve the content of my_method without executing it? I am looking to get the code that it will run when executed:
"page.search('//p')"
Is there a way to do that in Ruby?
It's possible with pry gem, provided my_method source is saved in some file. pry adds source method to Method class:
require 'pry'
method = MyClass.instance_method(:my_method)
method.source
# => " def my_method\n page.search('//p')\n end"

Creating gem and trying to reference ApplicationController

I'm creating a gem to create an around_filter on my ApplicationController in all projects that the gem is in. This is my first gem and I'm having a few concerns.
I included rails as a dependency in the gemspec file, but how would I reference anything in rails?
Would I do something like require 'rails' at the top of my file, then do something like
Rails::Path::To::ApplicationController? I understand I could do something like:
Module MyGem
def self.included(klass)
klass.class_eval do
around_filter do |controller, action|
#insert code here
end
end
end
end
Then, in my Rails app I would include it in my Rails ApplicationController, but I don't want to have to include it. Of course, I might have to do some additional config for even that to work, but that is the gist of my crux. How would I reference ApplicationController in my gem? Do I just assume I have Rails since it is a dependency now and I should be able to freely call upon it in my ruby files?

how to skip before_action from alchemy-devise user controller and user session controller? Rails

I have a project that is using alchemy cms and alchemy-devise gem. The gem has a method executed in the controllers of the gem as a before_action
How can I skip this method from being executed directly from the gem?
https://github.com/magiclabs/alchemy-devise/blob/master/app/controllers/alchemy/users_controller.rb
line 6 and block on line 40
this code comes directly from the gem, how can i stop it from been executed?
You want to prevent the user from being redirected to the dashboard, right?
I don't know why you want to do that, but to answer the question you could do following (untested):
# config/application.rb
module YourApp
class Application < Rails::Application
# ...
config.to_prepare do
Alchemy::UsersController.skip_before_action :check_user_count
end
end
end
For my interest: Why do you want that?

Resources