module Filemaker::Model::Selectable

Public Instance Methods

custom_query(criterion) click to toggle source
# File lib/filemaker/model/selectable.rb, line 125
def custom_query(criterion)
  chains.push(:custom)
  chains.delete(:where)
  chains.delete(:in)
  @selector = criterion
  self
end
find(criterion) click to toggle source

Find records based on model ID. If passed a hash, will use `where`. On the last resort, if we seriously can't find using `where`, we find it thru the `recid`. Is this a good design? We will see in production. Performance note: 2 HTTP requests if going that last resort route.

@example Find by model ID.

Model.find('CAID324')

@example Find with a Hash. This will delegate to `where`.

Model.find(name: 'Bob', salary: 4000)

@param [Integer, String, Hash] criterion

@return [Filemaker::Model::Criteria, Filemaker::Model]

# File lib/filemaker/model/selectable.rb, line 38
def find(criterion)
  return where(criterion) if criterion.is_a? Hash

  # Find using model ID (may not be the -recid)
  # Always append double '=' for ID instead of just one '='
  id = criterion.to_s.gsub(/\A=*/, '==')

  # If we are finding with ID, we just limit to one and return
  # immediately. Last resort is to use the recid to find.
  where(klass.identity.name => id).first || recid(criterion)
end
Also aliased as: id
id(criterion)
Alias for: find
in(criterion, negating = false) { |options| ... } click to toggle source

Find records based on FileMaker's compound find syntax.

@example Find using a single hash

Model.in(nationality: %w(Singapore Malaysia))

@example Find using an array of hashes

Model.in([{nationality: %w(Singapore Malaysia)}, {age: [20, 30]}])

@param [Hash, Array]

@return [Filemaker::Model::Criteria]

# File lib/filemaker/model/selectable.rb, line 105
def in(criterion, negating = false)
  if chains.include?(:where)
    raise Filemaker::Errors::MixedClauseError,
          "Can't mix 'in' with 'where'."
  end

  chains.push(:in)
  chains.delete(:where)
  @selector ||= []

  become_array(criterion).each do |hash|
    accepted_hash = klass.with_model_fields_for_query(hash)
    accepted_hash['-omit'] = true if negating
    @selector << accepted_hash
  end

  yield options if block_given?
  self
end
not_in(criterion) click to toggle source

Simply append '-omit' => true to all criteria

# File lib/filemaker/model/selectable.rb, line 134
def not_in(criterion)
  self.in(criterion, true)
end
or(criterion) { |options| ... } click to toggle source

Used with `where` to specify how the queries are combined. Default is 'and', so you won't find any `and` method.

@example Mix with where to 'or' query

Model.where(name: 'Bob').or(age: '50')

@param [Hash] criterion Hash criterion

@return [Filemaker::Model::Criteria]

# File lib/filemaker/model/selectable.rb, line 147
def or(criterion)
  if chains.include?(:in)
    raise Filemaker::Errors::MixedClauseError,
          "Can't mix 'or' with 'in'."
  end

  @selector ||= {}
  selector.merge!(klass.with_model_fields_for_query(criterion))
  options[:lop] = 'or'
  yield options if block_given?
  self
end
recid(id) click to toggle source

Using FileMaker's internal ID to find the record.

# File lib/filemaker/model/selectable.rb, line 51
def recid(id)
  return nil if id.blank?

  @selector = {} # We want to clear the selector when it comes to recid
  selector['-recid'] = id
  chains.push(:where) unless chains.include?(:where) # No double :where
  first
end
where(criterion) { |options| ... } click to toggle source

Find records based on query hash.

@param [Hash] criterion Hash criterion

@return [Filemaker::Model::Criteria]

# File lib/filemaker/model/selectable.rb, line 9
def where(criterion)
  if chains.include?(:in)
    raise Filemaker::Errors::MixedClauseError,
          "Can't mix 'where' with 'in'."
  end

  chains.push(:where)
  chains.delete(:in)

  @selector ||= {}
  selector.merge!(klass.with_model_fields_for_query(criterion))
  yield options if block_given?
  self
end

Private Instance Methods

become_array(value) click to toggle source
# File lib/filemaker/model/selectable.rb, line 162
def become_array(value)
  value.is_a?(Array) ? value : [value]
end