Skip to content

relationship/collection .first transfers entire scope to client #296

Open
@catmando

Description

@catmando

SomeModelWithLotsOfData.first will transfer the entire table to the client then select the first item.

This patch appears to fix, and can be added as is to your ApplicationRecord file at the start.

module ReactiveRecord
  class Collection

   # THIS IS THE KEY PART OF THE PATCH... DO THE SAME THING AS last FOR first
    def first(n = nil)
      if n
        apply_scope(:__hyperstack_internal_scoped_first_n, n)
      else
        __hyperstack_internal_scoped_first
      end
    end
  end

    def method_missing(method, *args, &block)
      if args.count == 1 && method.start_with?('find_by_')
        find_by(method.sub(/^find_by_/, '') => args[0])
      elsif [].respond_to? method
        all.send(method, *args, &block)
      elsif ScopeDescription.find(@target_klass, method)
        apply_scope(method, *args)
      elsif @target_klass.respond_to?(method) && ScopeDescription.find(@target_klass, "_#{method}")
       # .first was being used here.  change to [0] so we don't get into infinite recursion
        apply_scope("_#{method}", *args)[0]
      else
        super
      end
    end
end if RUBY_ENGINE == 'opal'

module ActiveRecord
  class Base
    # define the scope and finder method used by the first method above

    finder_method :__hyperstack_internal_scoped_first do
      first
    end

    scope :__hyperstack_internal_scoped_first_n, ->(n) { first(n) }

    # this method was using collection.first rather than collection[0]

    def self.__hyperstack_internal_scoped_find_by(attrs)
      collection = all.apply_scope(:___hyperstack_internal_scoped_find_by, attrs)
      if !collection.collection
        collection._find_by_initializer(self, attrs)
      else
        # use collection[0] rather than collection.first to avoid infinite recursion
        collection[0]
      end
    end
  end unless Base.respond_to? :__hyperstack_internal_scoped_first_n # only needed for the patch
end

Test case might be interesting to create....

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinggood first issueGood for newcomers

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions