Search code examples
ruby-on-railsrubyrspecruby-on-rails-5

rspec: Helpers Method on Model undefined method


I'm getting an issue with helpers method included in my model.

I include my helpers as follow:

class Booking < ApplicationRecord
  include BookingsHelper
  include PaymentsHelper

Both of BookingsHelper and PaymentsHelper have slack_notify function. So in order to call the good slack_notify function I call this function as below:

BookingsHelper.slack_notify(self)
PaymentsHelper.slack_notify(requester.email, 'danger', 'booking:proceed_payment', e.message)

When I run my test (with rspec) I got:

     Failure/Error: BookingsHelper.slack_notify(self)

     NoMethodError:
       undefined method `slack_notify' for BookingsHelper:Module

And I noticed if I change: BookingsHelper.slack_notify(self) by slack_notify(self) it works but call the slack_notify in PaymentsHelper so I don't really understand what's happening. And if I remove the PaymentHelper it call the good one

If someone could highlight me on this behavior, I would be really interested to understand whats going on

Thanks


Solution

  • You are using Mixin here.

    A mixin can basically be thought of as a set of code that can be added to one or more classes to add additional capabilities without using inheritance. In Ruby, a mixin is code wrapped up in a module that a class can include or extend

    You do not access helper methods like the static methods but you call them directly, in your example you should call slack_notify directly without having module name before. When you include two modules which have the same method name then the last one overrides the previous one. If you do not want it to be overriden then you have to define in the module like that:

    def BookingsHelper.slack_notify
      // your code
    end
    

    and

    def PaymentsHelper.slack_notify
      // your code
    end
    

    see the example about sin and cos here: https://www.tutorialspoint.com/ruby/ruby_modules.htm

    Read more about mixins and you will have better understanding of what is going on here.