Call Before Methods in Model on Ruby

call before methods in model on ruby

You can do this with prepend. prepend is like include in that it adds a module to the ancestors of the class, however instead of adding it after the class it adds it before.

This means that if a method exists both in the prepended module and the class then the module implementation is called first (and it can optionally call super if it wants to call the base class).

This allows you to write a hooks module like so:

module Hooks
def before(*method_names)
to_prepend = Module.new do
method_names.each do |name|
define_method(name) do |*args, &block|
puts "before #{name}"
super(*args,&block)
end
end
end
prepend to_prepend
end
end

class Example
extend Hooks
before :foo, :bar

def foo
puts "in foo"
end
def bar
puts "in bar"
end
end

In real use you would probably want to stash that module somewhere so that each call to before doesn't create a new module but that is just an inplementation detail

before and after method call on models in ruby on rails, do thing

If you really want to wrap every method call (or even the ones defined by the target class itself), you can define a module that does 2 things,

  • Get all the instance_methods and wraps them with your custom code
  • Override the method_added method call and wrap every new method that is added with the same custom code

A good example using this strategy is answered here. You can customize this to take additional except configuration and exclude those methods.

The meta-programming going on here is to rewrite each method as it is injected into the instance.


Another option is to wrap only specific method calls with your custom code, if you know which ones you'll need to cache. It will be less overhead and cleaner implementation.

For implementation, you can use the same meta-programming approach as described in the first example. One more approach can be to add an alias to the original method and rewrite the method to include your hook. Something like,

def add_before_hook(method_name)
class_eval do
without = :"#{method_name}_without_before_each_method"
alias_method without, method_name

define_method method_name do |*args, &block|
puts 'called before'
send without, *args, &block
end
end
end

The problem with the second approach is that it pollutes your method namespace by adding a duplicate method for each of your instance methods.

How to call method before index and new from model

You can pass a lambda, in this case {@interests = Widget.interests current_user}, into before_action to achieve what you want.

app/controllers/widgets_controller.rb

class WidgetsController < ApplicationController
before_action(only: [:show]) {@interests = Widget.interests current_user}

def show
# do something with @interests
end
end

app/models/widget.rb

class Widget < ActiveRecord::Base
def self.interests(user)
City.joins("INNER JOIN property_of_interests ON property_of_interests.city_id = cities.id").where(:property_of_interests => {:user_id => user})
end
end

Rails call back before every calling a method before every static method

Try this

class A

def self.hello
print "how are"

end

def self.before_stuff
print "you"
end

begin
print "hello,"
end
end

A.hello

Call a model method in a Controller

To complete davidb's answer, two things you're doing wrong are:

1) you're calling a model's function from a controller, when the model function is only defined in the model itself. So you do need to call

Project.form_search

and define the function with

def self.form_search

2) you're calling params from the model. In the MVC architecture, the model doesn't know anything about the request, so params is not defined there. Instead, you'll need to pass the variable to your function like you're already doing...

Ruby on Rails: Calling Model method in view

It seems that paypal_url is a private method and you are trying to call it from outside of its class.

In your Order class you probably have the keyword private. Every method below that keyword will be declared private (as opposed to public) and an error will be thrown if you try to call it from outside the class. Private methods can only be called from within the class where they are defined. So try moving the definition of paypal_url so that it appears before private in your class.

You can read more about how this works here, and about the reasons behind it here.



Related Topics



Leave a reply



Submit