Is it possible to invoke a helper_method from another Helper? - ruby-on-rails

I have two Helpers, ExamsHelper and ResultsHelper
exams_helper.rb
module ExamsHelper
def get_data
...
end
end
results_helper.rb
module ResultsHelper
def find_result
...
end
end
Is it possible to access the get_data method in ResultsHelper.
I know that if I am declaring it on the ApplicationHelper, I can access it. Is there any other solution for it?

You can always use include:
module ResultsHelper
include ExamsHelper
def find_result
get_data # works
end
end

Related

Is it okay to call a private method of a parent class's subclass from a module which is included in the parent class in rails?

Is it okay to call a private method of a parent class's subclass from a module which is included in the parent class especially when it concerns ApplicationController, Controllers and lib modules in Rails?
Consider if required to change the controller name the method name to reflect the model name(to Article) change.
I feel this is really bad coding and wanted to know what community thinks about this
Example from a Rails Application:
/lib/some_module.rb
module SomeModule
include SomeModuleResource
def filtering_method
calling_method
end
def calling_method
fetch_object
end
end
/lib/some_module_resource.rb
module SomeModuleResource
def fetch_object
note
end
end
/app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
include SomeModule
before_action :filtering_method
end
/app/controllers/notes_controller.rb
class NotesController < ApplicationController
def show
end
private
def note
#note ||= Note.find(param[:id]))
end
end
I'm of the opinion that this is not necessary bad, although when you expect a certain interface (methods, variables, etc.) from the class that includes the module I would add the following:
module SomeModuleResource
def fetch_object
note
end
private
def note
raise NotImplementedError
end
end
This way, when #note is called without implementing it (because you forgot it was needed or whatever) a NotImplementedError is raised.
Another option is to work around it and create a more general solution. For example, if all controllers behave the same way you described above you can do the following:
module SomeModuleResource
def fetch_object
note
end
private
def note
klass = params[:controller].classify.constantize
instance = klass.find(params[:id])
var_name = "##{klass.underscore}"
instance_variable_set(var_name, instance) unless instance_variable_get(var_name)
end
end
You could also create a class helper method like before_action so that you can pass your own implementation.
module SomeModule
include SomeModuleResource
def self.included(base)
base.extend(ClassMethods)
end
def filtering_method
calling_method
end
def calling_method
fetch_object
end
module ClassMethods
def custom_before_action(&block)
define_method(:note, &block)
private :note
before_action :filtering_method
end
end
end
Now you can use custom_before_filter { #note ||= Note.find(params[:id]) } in every controller (after including).
The above is just to present you with ideas. I'm sure you could find better solution to the problem, but this hopefully points you in the right direction.
See: Alternatives to abstract classes in Ruby?. Or search for abstract classes in Ruby and you'll find more on this subject.

How can I redirect from a Module?

I tried TO Google Can I redirect_to in rails modules but couldn't come up with anything. Basically, I have a method that I am going to use across a couple of Controllers.
lib/route_module.rb
module RouteModule
def self.user_has_active_chocolate(c_id, u_id)
chocolate_id = c_id
user_id = u_id
unless UserChocolate.where(id: chocolate_id).empty?
if UserChocolate.where(id: chocolate_id).last.active?
true
else
false
# BREAKS OVER HERE...
redirect_to "/user/new-chocolate/#{user_id}"
end
else
false
redirect_to "/admin"
end
end
end
app/controllers/user_controllers.rb
include RouteModule
before_filter :thingz, only: [:display_user_chocolate]
# private
def thingz
RouteModule.user_has_active_chocolate(params["chocolate_id"], params["user_id"])
end
But... whenever I run this... It will break as soon as it hit's redirect_to.
undefined method `redirect_to' for RouteModule:Module
My other option is use ActiveSupport::Concerns but I just trouble converting this Module into a Concern.
When you include a module, it acts as a mixin. That said, you include and get all the methods of the module in the context of your class. The proper way would be:
module RouteModule
def user_has_active_chocolate(c_id, u_id) # NO self
...
end
end
And in the class:
include RouteModule
def thingz
# NO module method call (NO RouteModule)
user_has_active_chocolate(params["chocolate_id"], params["user_id"])
end

How to put helper methods and private methods in helpers

I have some helpers and private methods in a controller, and I want to have the same helpers and private methods in another controller. So I moved that code to module and tried to include the module in the second controller. But I can't seem to do it, because it says undefined method helper method for the DashboardHelper. Is there anyway to accomplish what I am trying to do?
Here is the code
module DashboardHelper
def get_date(log)
end
def get_working_hours(log)
end
helper_method :get_date, :get_working_hours
private
def employee_params
end
def identify_employee
end
def check_is_arrived
end
def calculate_time_percentage
end
end
class AccountController < ApplicationController
include DashboardHelper
end
hello gates you have to include extend ActiveSupport::Concern in your concern .
This should not be in your helper folder instead pull it somewhere in you concern folder
the end file may look like
module DashboardHelper
extend ActiveSupport::Concern
module ClassMethods
def get_date(log)
end
def get_working_hours(log)
end
helper_method :get_date, :get_working_hours
private
def employee_params
end
def identify_employee
end
def check_is_arrived
end
def calculate_time_percentage
end
end
end

Access variables outside a class method

How do I access things outside of a class method in rails? I get an error like undefined method do_something_else
module Thing
def self.do_something
do_something_else
end
def do_something_else
end
end
Here's a good reference that shows the difference between class_methods/singleton_methods and instance_methods.
In your case, you cannot access the instance method(do_something_else) without an instance.
To solve this, you have to include the module in a class and use an instance of that class.
module Thing
def self.do_something
Logic.new.do_something_else
end
def do_something_else
#perform the logic and actions here
end
end
class Logic
include Thing
end
If you would like to think of it differently though, here's what I'd propose:
module Thing
def self.do_something_else
# perform your logic and actions here
end
def do_something
# this is possible because do_something_else is defined on the module Thing
Thing.do_something_else
end
end
Try this
def self.do_something
Thing.new.do_something_else
end

Ruby: add method to the existing module

There is a module:
module ActionDispatch
module Routing
end
end
And methods:
def add_movie_path
end
def edit_movie_path
end
How I can add to module Routing this methods?
Is this only way?
Try:
module ActionDispatch
module Routing
def add_movie_path
end
def edit_movie_path
end
module_function :edit_movie_path
end
end
So that then you can do a call like it is a instance method like so:
class Make
include ActionDispatch::Routing
end
class MakeAll
def only_needs_the_one_method
ActionDispatch::Routing.edit_movie_path
end
end
You can also define it as a class method by using self.class_name and then directly access it like so:
module ActionDispatch
module Routing
def self.add_movie_path
end
def self.edit_movie_path
end
end
end
class Make
include ActionDispatch::Routing
def do_something
ActionDispatch::Routing.add_movie_path
end
end
class MakeAll
def only_needs_the_one_method
ActionDispatch::Routing.edit_movie_path
end
end
See that Modules Magic for more.
Unless I misunderstand what you're asking, how about something like:
module ActionDispatch
module Routing
def add_movie_path
end
def edit_movie_path
end
end
end
Alternatively, you could use module_eval.
Simply put your methods inside the module.
module ActionDispatch
module Routing
def add_movie_path
end
def edit_movie_path
end
end
end

Resources