Ravi
Ravi

Reputation: 304

Rails - ArgumentError wrong number of arguments given 3, expected 2

I have been stuck on a seemingly simple issue for the past days, please help. I have three models:

organization.rb

class Organization < ApplicationRecord
    # resourcify
  extend FriendlyId
  friendly_id :slug_candidates, :use => [:slugged, :finders]

  belongs_to :owner, class_name: 'User', foreign_key: 'owner_id', inverse_of: :organization
  belongs_to :country

    has_many :stores
    has_many :organization_users
  has_many :users, through: :organization_users
  has_many :addresses, as: :addressable, dependent: :destroy
  has_many :organization_catalogs
  has_many :store_catalogs

  has_one :account
  has_one :subscription, through: :account

  # accepts_nested_attributes_for :owner, :addresses

  validates :name, presence: true
  validates :name, uniqueness: true
  validates :subdomain, uniqueness: true

  after_create :create_master_catalog
  after_create :create_account

  def store_users
    _users = {}
    stores.each do |store|
      _users["#{store.id}"] = User.store_users(store.id)
    end
    _users
  end

  def catalogs
    Catalog.where organization_id: id
  end

  private

    def slug_candidates
      [
        :subdomain,
        :name
      ]
    end

    def create_master_catalog
      OrganizationCatalog.create! name: 'Master Catalog', organization_id: self.id, master: true
    end

    def create_account
      plan = Subscription::SUBSCRIPTION_PLANS[:trial]
      trial_period = Subscription::TRIAL_PERIOD
      subscription = Subscription.create! name: plan[:name], price: (plan[:price].to_i * 100), currency: 'INR', trial_start: Time.now, billing_cycle: 30.days.to_s, trial_end: ( Time.now + trial_period), trial_period: trial_period
      Account.create! organization_id: self.id, subscription_id: subscription.id
    end
end

user.rb

# This class is for all clients
class User < ApplicationRecord
  rolify
  extend FriendlyId
  friendly_id :uid, :use => [:slugged, :finders]
  devise :invitable, :database_authenticatable, :recoverable, :rememberable, :validatable, 
         :lockable, :timeoutable, :trackable, :uid #, :omniauthable, :confirmable, :registerable, 

  attr_accessor :skip_password_validation, :role, :store_ids

  has_many :invitations, class_name: 'User', as: :invited_by
  has_one :organization_user, dependent: :destroy
  has_one :organization, class_name: 'Organization', foreign_key: 'owner_id', inverse_of: :owner
  has_one :organization, through: :organization_user
  has_one :store_user, dependent: :destroy
  has_one :store, through: :store_user

  scope :organization_users, -> (organization_id){ 
                                                  includes(:organization_user)
                                                  .where(
                                                    organization_users: { organization_id: organization_id }
                                                  )
                                                }
  scope :store_users, -> (store_id){ 
                                    includes(:store_user)
                                    .where(
                                      user_type: USER_TYPES[:store], 
                                      store_users: { store_id: store_id }
                                    )
                                  }

  # before_create :verify_and_create_user_type

  USER_TYPES = { 
                 store: "Store", 
          organization: "Organization",
                 admin: "Admin"
        }

  validates :email, presence: true, uniqueness: true
  validates :first_name, presence: true
  validates :last_name, presence: true

  # validates :user_type,
        #     :inclusion => { :in => USER_TYPES.values },
        #     :allow_nil => false,
  #       presence: true

  before_invitation_created :assign_default_store_role

  attr_reader :store_id

  def assign_default_store_role
    # self.add_role :employee
  end

  def store_user?
    self.store_user.present?
  end

  def organization_user?
    self.organization_user.present?
  end

  def display_name
    "#{first_name} #{last_name}"
  end

  def admin?
    admin
  end

  protected

    def remove_previous_roles(role)
      if role.resource
        Rails.logger.debug "User::remove_previous_roles: Adding the role of #{role.name} for #{role.resource_type} #{role.resource_id} to user #{id}"
        #remove any pre-existing role this user has to the resource
        remove_role nil, role.resource
      else
        remove_role nil
      end
    end

    def password_required?
      return false if skip_password_validation
      super
    end

end

organization_user.rb

class OrganizationUser < ApplicationRecord
    belongs_to :organization
    belongs_to :user
end

I have been stuck with this error for the past 2 days and I have ran out of ideas on how to fix this. I keep getting ArgumentError wrong number of arguments (given 3, expected 2) and I am not sure why. Error doesn't even have any backtrace as well, so I don't even know where it is coming from. Errors seems simple enough telling me that I am passing 3 arguments when only 2 are expected. but the thing is when I get this error, I don't even pass any arguments.

The error occurs in the following cases:

org = Organization.first
org.users
org = Organization.first
User.includes(:organization_user).where(organization_user: { organization_id: org.id})
user = User.first
user.add_role :manager
store = Store.first
store.users

This probably indicates that there is some issue with user model but I have tried a lot of things and none of them seems to work.

The error doesn't leave any backtrace. Console shot

Error from log file:

Error from log file

Code for the above error:

organizations_controller.rb

class OrganizationsController < ApplicationController
  skip_before_action :authenticate_user!, only: [:new, :create, :details, :update]
  load_and_authorize_resource except: [:new, :create, :details, :update]
  layout :resolve_layout

  def index
    @stores = Store.all
  end

  def new
    @org = Organization.new
    @org.users.build
  end

  def create
    @org = Organization.new(sign_up_params)

    respond_to do |format|
      if @org.save(validate: false)
        add_owner_role @org
        format.html { render action: :details }
      else
        format.html { render action: :new, alert: 'There were problems creating your account. Please rectify the errors.' }
        format.json  { render :json => @org.errors,
                        :status => :unprocessable_entity }
      end
    end
  end

  def show   
    # respond_to do |format|
    #   format.html  # show.html.erb
    #   format.json  { render :json => @store }
    # end
  end

  def edit
  end

  def details
  end

  def update
    @org = Organization.find params[:id]
    respond_to do |format|
      if @org.update(subdomain: organization_details_params[:subdomain])
        @org.addresses << Address.create(organization_details_params[:address])
        format.html  { redirect_to(root_path,
                      :notice => 'Your account has been successfully created. Please continue by logging in.') }
        format.json  { head :no_content }
      else
        format.html  { render :action => "details" }
        format.json  { render :json => @org.errors,
                      :status => :unprocessable_entity }
      end
    end
  end

  def destroy
    # @store.destroy

    # respond_to do |format|
    #   format.html { redirect_to stores_url }
    #   format.json { head :no_content }
    # end
  end

  private

    def add_owner_role organization
      organization.owner.add_role :owner, organization
      OrganizationUser.create!(organization_id: organization.id, user_id: organization.owner.id)
    end

    def store_params
      params.require(:store).permit(:id, :name, :description)
    end

    def organization_details_params
      params.require(:organization).permit(:subdomain, address: [:address, :address1, :address2, :city_id, :country_id, :state_id, :registered, :pincode])
    end

    def sign_up_params
      params.require(:organization).permit(:name, :country_id, users_attributes: [:first_name, :last_name, :email, :mobile, :password, :password_confirmation])
    end

    def resolve_layout
      case action_name
      when "new", "create", "details"
        "users"
      else
        "application"
      end
    end
end

But the User model in itself works correctly. Like I can do the following:

u = User.first
org = Organization.first
org.organization_users.first.user
#<User:0x00007fb7daa23570>

Trying to capture the error with begin and rescue: enter image description here

I am not sure if it'll help, but I am using rails 6.0.0rc1 and ruby 2.6.3.

Please do let me know if there is anything else required to debug this.

Upvotes: 2

Views: 3662

Answers (1)

Ravi
Ravi

Reputation: 304

I am still not sure what the cause of the problem was but it got fixed as soon as I reverted my Gemfile.lock to its previous state.

I still don't see from the diff what could have caused this. Only changes that I are there are minor upgrades to a couple of gems.

Let me know if someone would like to look at them.

Upvotes: 3

Related Questions