ruby-on-railsrubyrails-activerecordsingle-table-inheritance

Rails How to create a Model, Controller and View using Inheritance?


I am working on this application that uses inheritance on models, but it is getting this error message on the view:

superclass mismatch for class BankTransfer

I have created an MVC called “payment_methods” Using the scaffold command:

rails g scaffold payment_methods type:string is_active:boolean

In the model file, payment_method.rb, I have included the classes:

class PaymentMethod < ApplicationRecord

end

class BankTransfer < PaymentMethod

end

class PayPal < PaymentMethod
end

Using rails console, with the commands: BankTransfer.create and Paypal.create, was possible to create on database the objects.

So running on rails console: PaymentMethod.all i get the return (that shows me that it was correctly save on the database):

PaymentMethod.all
  PaymentMethod Load (0.2ms)  SELECT "payment_methods".* FROM "payment_methods"                                                                 
 =>                                                                  
[#<Boleto:0x00007f995d403000                                         
  id: 1,                                                             
  type: "BankTransfer",                                                    
  is_active: nil,                                                    
  created_at: Fri, 15 Jul 2022 16:46:29.759160000 UTC +00:00,        
  updated_at: Fri, 15 Jul 2022 16:46:29.759160000 UTC +00:00>,       
 #<Stripe:0x00007f995d402da8
  id: 2,
  type: "PayPal",
  is_active: nil,
  created_at: Fri, 15 Jul 2022 16:46:56.087921000 UTC +00:00,
  updated_at: Fri, 15 Jul 2022 16:46:56.087921000 UTC +00:00>] 

The views and the controller were created automatically.

index.html.erb

<div id="payment_methods">
  <% @payment_methods.each do |payment_method| %>
    <%= render payment_method %>
    <p>
      <%= link_to "Show this payment method", payment_method %>
    </p>
  <% end %>
</div>

payment_methods_controller.rb

class PaymentMethodsController < ApplicationController
  before_action :set_payment_method, only: %i[ show edit update destroy ]

  def index
    @payment_methods = PaymentMethod.all
  end

  def show
  end

  def new
    @payment_method = PaymentMethod.new
  end

(...)

  private
    def set_payment_method
      @payment_method = PaymentMethod.find(params[:id])
    end

    def payment_method_params
      params.require(:payment_method).permit(:type, :is_active)
    end
end

What should I fix to be able to see a list of payment methods on the frontend. Instead of the error message superclass mismatch for class.


Solution

  • If you're going to have a 'Stripe' value in your payment_methods.type column then you'll need to have a Stripe class that looks like this:

    class Stripe < PaymentMethod
      # ...
    end
    

    Similarly for other payment_methods.type values.

    The problem is that the stripe gem defines module Stripe, that's where your "superclass mismatch" error comes from.

    The easiest solution would be to use a different name for your Stripe class, maybe StripePaymentMethod (and then PayPalPaymentMethod, BankTransferPaymentMethod, ... for consistency).