Module: DataMapper::Model

Defined in:
lib/dm-ar-finders.rb

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missingObject (private) Also known as: method_missing_without_find_by



160
161
162
163
164
165
166
167
168
169
# File 'lib/dm-ar-finders.rb', line 160

def method_missing_with_find_by(method, *args, &block)
  if match = matches_dynamic_finder?(method)
    finder          = determine_finder(match)
    attribute_names = extract_attribute_names_from_match(match)

    send(finder, Hash[ attribute_names.zip(args) ])
  else
    method_missing_without_find_by(method, *args, &block)
  end
end

Instance Method Details

#find(id) ⇒ Resource, ... #find(symbol) ⇒ Resource, ...

Lookup the resource or resources

Overloads:

  • #find(id) ⇒ Resource, ...

    Parameters:

    • id (Integer)

      the primary key value for the resource

  • #find(symbol) ⇒ Resource, ...

    Parameters:

    • symbol (Symbol)

      either :first, :last, or :all

Parameters:

  • symbol_or_id (Integer, Symbol)

    either a symbol (:first, :last, or :all) or the primary key value for the resource the primary key value for the resource

Returns:

  • (Resource)

    A collection containing all records for this model if asked for :all

  • (DataMapper::Collection)

    the resource that was found if given an ID or asked for :first or :last.

  • (nil)

    nil if no resource was found



27
28
29
30
31
32
33
34
# File 'lib/dm-ar-finders.rb', line 27

def find(symbol_or_id)
  case symbol_or_id
    when :first then first
    when :last  then last
    when :all   then all
    else             get(symbol_or_id)
  end
end

#find_by_sql(string_query, options = {}) ⇒ DataMapper::Collection #find_by_sql(dm_query, options = {}) ⇒ DataMapper::Collection

Find resources by providing your own SQL query or DataMapper::Query instance.

Examples:

Query with bind values

MyClass.find_by_sql(["SELECT id FROM my_classes WHERE county = ?",
  selected_county])

String query

MyClass.find_by_sql("SELECT id FROM my_classes LIMIT 1")

Query with properties option

MyClass.find_by_sql("SELECT id, name FROM my_classes LIMIT 1",
  :properties => [:id, :name])

Query with repository

MyClass.find_by_sql(["SELECT id FROM my_classes WHERE county = ?",
  selected_county], :properties => MyClass.property[:id],
  :repository => :county_repo)

Overloads:

  • #find_by_sql(string_query, options = {}) ⇒ DataMapper::Collection

    Parameters:

    • sql_or_query (String)

      A string containing an SQL query to execute.

    • options (Hash) (defaults to: {})

      A hash containing extra options.

  • #find_by_sql(dm_query, options = {}) ⇒ DataMapper::Collection

    Parameters:

    • sql_or_query (DataMapper::Query)

      A DataMapper::Query instance to be used to generate an SQL query.

    • options (Hash) (defaults to: {})

      A hash containing extra options.

Parameters:

  • sql_or_query (Array)

    An array whose first element is an SQL query, and the other elements are bind values for the query.

  • options (Hash) (defaults to: {})

    A hash containing extra options.

Options Hash (options):

  • :reload (true, false) — default: false

    Whether to reload any matching resources which are already loaded.

  • :properties (Symbol, Array, DataMapper::Property, DataMapper::PropertySet)

    Specific properties to be loaded. May be a single symbol, a Property instance, an array of Properties, or a PropertySet.

  • :repository (Symbol)

    The repository to query. Uses the model default if none is specified.

Returns:

  • (DataMapper::Collection)

    A collection containing any records which matched your query.

Raises:

  • (ArgumentError)


87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/dm-ar-finders.rb', line 87

def find_by_sql(sql_or_query, options = {})
  # Figure out what the user passed in.
  case sql_or_query
  when Array
    sql, *bind_values = sql_or_query
  when String
    sql, bind_values = sql_or_query, []
  when DataMapper::Query
    sql, bind_values = repository.adapter.send(:select_statement, sql_or_query)
  else
    raise ArgumentError, '#find_by_sql requires a query of some kind to work'
  end

  # Sort out the options.
  repository = repository(options.fetch(:repository, default_repository_name))

  if options.key?(:properties)
    if options[:properties].kind_of?(DataMapper::PropertySet)
      properties = options[:properties]
    else
      # Normalize properties into PropertySet[Property].
      properties = Array(options[:properties]).map! do |prop|
        prop.kind_of?(Symbol) ? self.properties[prop] : prop
      end

      properties = DataMapper::PropertySet.new(properties)
    end
  else
    properties = self.properties(repository.name)
  end

  unless defined?(Adapters::DataObjectsAdapter) && repository.adapter.kind_of?(Adapters::DataObjectsAdapter)
    raise '#find_by_sql only available for Repositories served by a DataObjectsAdapter'
  end

  records = []

  repository.adapter.send(:with_connection) do |connection|
    reader = connection.create_command(sql).execute_reader(*bind_values)
    fields = properties.field_map.values_at(*reader.fields).compact

    begin
      while reader.next!
        records << Hash[ fields.zip(reader.values) ]
      end
    ensure
      reader.close
    end
  end

  query = Query.new(repository, self,
    :fields => properties, :reload => options.fetch(:reload, false))

  Collection.new(query, query.model.load(records, query))
end