Module: DataMapper::Resource::ClassMethods

Public Visibility

Public Class Method Summary

extended(model)

Public Instance Method Summary

#[](key)
#all(options = {})
#avg(*args)

Get the average value of a property.

#copy(source, destination, options = {})

TODO SPEC.

#count(*args)

Count results (given the conditions).

#create(attributes = {})

Create an instance of Resource with the given attributes.

#create!(attributes = {})

Dangerous version of #create.

#find_by_sql(*args)

Find instances by manually providing SQL.

Returns:

#find_or_create(search_attributes, create_attributes = {})
#first(options = {})
#first_or_create(first_options, create_options = {})
#get(*key)
#get!(key)
#inheritance_property(repository_name = default_repository_name)
#inherited(target)
#key(repository_name = default_repository_name)
#max(*args)

Get the highest value of a property.

#min(*args)

Get the lowest value of a property.

#properties(repository_name = default_repository_name)
#property(name, type, options = {})

defines a property on the resource.

#repositories
#repository(name = nil, &block)

Get the repository with a given name, or the default one for the current context, or the default one for this class.

Returns:

#storage_exists?(repository_name = default_repository_name)
#storage_name(repository_name = default_repository_name)

the name of the storage recepticle for this resource.

Returns:

#storage_names

the names of the storage recepticles for this resource across all repositories.

Returns:

#sum(*args)

Get the total value of a property.

#transaction(&block)

Produce a new Transaction for this Resource class.

Returns:

Public Class Method Details

extended

public extended(model)
[View source]


535
536
537
538
# File 'dm-core/lib/dm-core/resource.rb', line 535

def self.extended(model)
  model.instance_variable_set(:@storage_names, Hash.new { |h,k| h[k] = repository(k).adapter.resource_naming_convention.call(model.instance_eval do default_storage_name end) })
  model.instance_variable_set(:@properties,    Hash.new { |h,k| h[k] = k == Repository.default_name ? PropertySet.new : h[Repository.default_name].dup })
end

Public Instance Method Details

[]

public [](key)
[View source]


652
653
654
655
# File 'dm-core/lib/dm-core/resource.rb', line 652

def [](key)
  warn("Resource::[] is deprecated. Use Resource::get! instead.")
  get!(key)
end

all

public all(options = {})

Meta Tags

See Also:

Repository#all
[View source]


677
678
679
680
681
682
683
684
685
686
687
# File 'dm-core/lib/dm-core/resource.rb', line 677

def all(options = {})
  if Hash === options && options.has_key?(:repository)




    repository(options[:repository]).all(self, options)
  else
    repository.all(self, options)
  end
end

avg

public avg(*args)

Get the average value of a property

Example

  Friend.avg(:age) # returns the average age of friends
  Friend.avg(:age, :conditions => [ 'gender = ?', 'female' ]) # returns the average age of the female friends

Parameters

property<Symbol>:the property you wish to get the average value of
opts<Hash, Symbol>:the conditions

Returns

<Integer>:return the average value of a property given the conditions

[View source]


85
86
87
88
89
90
# File 'dm-more/dm-aggregates/lib/dm-aggregates/resource.rb', line 85

def avg(*args)
  with_repository_and_property(*args) do |repository,property,options|
    check_property_is_number(property)
    repository.avg(self, property, options)
  end
end

copy

public copy(source, destination, options = {})

TODO SPEC

[View source]


720
721
722
723
724
725
726
# File 'dm-core/lib/dm-core/resource.rb', line 720

def copy(source, destination, options = {})
  repository(destination) do
    repository(source).all(self, options).each do |resource|
      self.create(resource)
    end
  end
end

count

public count(*args)

Count results (given the conditions)

Example

  Friend.count # returns count of all friends
  Friend.count(:age.gt => 18) # returns count of all friends older then 18
  Friend.count(:conditions => [ 'gender = ?', 'female' ]) # returns count of all your female friends
  Friend.count(:address) # returns count of all friends with an address (NULL values are not included)
  Friend.count(:address, :age.gt => 18) # returns count of all friends with an address that are older then 18
  Friend.count(:address, :conditions => [ 'gender = ?', 'female' ]) # returns count of all your female friends with an address

Parameters

property<Symbol>:of the property you with to count (optional)
opts<Hash, Symbol>:of the conditions

Returns

<Integer>:with the count of the results

[View source]


23
24
25
26
27
# File 'dm-more/dm-aggregates/lib/dm-aggregates/resource.rb', line 23

def count(*args)
  with_repository_and_property(*args) do |repository,property,options|
    repository.count(self, property, options)
  end
end

create

public create(attributes = {})

Create an instance of Resource with the given attributes

Meta Tags

Parameters:

<Hash(Symbol

> Object)> attributes hash of attributes to set

[View source]


700
701
702
703
704
705
# File 'dm-core/lib/dm-core/resource.rb', line 700

def create(attributes = {})
  resource = allocate
  resource.send(:initialize_with_attributes, attributes)
  resource.save
  resource
end

create!

public create!(attributes = {})

Dangerous version of #create. Raises if there is a failure

Meta Tags

Parameters:

<Hash(Symbol

> Object)> attributes hash of attributes to set

Raises:

<PersistenceError>

The resource could not be saved

[View source]


713
714
715
716
717
# File 'dm-core/lib/dm-core/resource.rb', line 713

def create!(attributes = {})
  resource = create(attributes)
  raise PersistenceError, "Resource not saved: :new_record => #{resource.new_record?}, :dirty_attributes => #{resource.dirty_attributes.inspect}" if resource.new_record?
  resource
end

find_by_sql

public find_by_sql(*args)

Find instances by manually providing SQL

Meta Tags

Parameters:

sql<String>

an SQL query to execute

<Array>

an Array containing a String (being the SQL query to execute) and the parameters to the query. example: ["SELECT name FROM users WHERE id = ?", id]

query<DataMapper::Query>

a prepared Query to execute.

opts<Hash>

an options hash. :repository<Symbol> the name of the repository to execute the query in. Defaults to self.default_repository_name. :reload<Boolean> whether to reload any instances found that already exist in the identity map. Defaults to false. :properties<Array> the Properties of the instance that the query loads. Must contain DataMapper::Properties. Defaults to self.properties.

Returns:

<Collection> the instance matched by the query.

[View source]


40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'dm-core/lib/dm-core/adapters/data_objects_adapter.rb', line 40

def find_by_sql(*args)
  sql = nil
  query = nil
  params = []
  properties = nil
  do_reload = false
  repository_name = default_repository_name
  args.each do |arg|
    if arg.is_a?(String)




      sql = arg
    elsif arg.is_a?(Array)
      sql = arg.first
      params = arg[1..-1]
    elsif arg.is_a?(DataMapper::Query)
      query = arg
    elsif arg.is_a?(Hash)
      repository_name = arg.delete(:repository) if arg.include?(:repository)
      properties = Array(arg.delete(:properties)) if arg.include?(:properties)
      do_reload = arg.delete(:reload) if arg.include?(:reload)
      raise "unknown options to #find_by_sql: #{arg.inspect}" unless arg.empty?
    end
  end

  the_repository = repository(repository_name)
  raise "#find_by_sql only available for Repositories served by a DataObjectsAdapter" unless the_repository.adapter.is_a?(DataMapper::Adapters::DataObjectsAdapter)

  if query




    sql = the_repository.adapter.send(:query_read_statement, query)
    params = query.fields
  end

  raise "#find_by_sql requires a query of some kind to work" unless sql

  properties ||= self.properties

  Collection.new(Query.new(repository, self)) do |set|
    repository.adapter.send(:with_connection) do |connection|
      begin
        command = connection.create_command(sql)
        command.set_types(properties.map { |p| p.primitive })

        reader = command.execute_reader(*params)

        while(reader.next!)




          set.load(reader.values, do_reload)
        end
      ensure
        reader.close if reader
      end
    end
  end
end

find_or_create

public find_or_create(search_attributes, create_attributes = {})
[View source]


9
10
11
# File 'dm-more/dm-ar-finders/lib/dm-ar-finders.rb', line 9

def find_or_create(search_attributes, create_attributes = {})
  first(search_attributes) || create(search_attributes.merge(create_attributes))
end

first

public first(options = {})

Meta Tags

See Also:

Repository#first
[View source]


688
689
690
691
692
693
694
695
696
697
698
# File 'dm-core/lib/dm-core/resource.rb', line 688

def first(options = {})
  if Hash === options && options.has_key?(:repository)




    repository(options[:repository]).first(self, options)
  else
    repository.first(self, options)
  end
end

first_or_create

public first_or_create(first_options, create_options = {})
[View source]


657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
# File 'dm-core/lib/dm-core/resource.rb', line 657

def first_or_create(first_options, create_options = {})
  first(first_options) || begin
    resource = allocate
    first_options = first_options.dup
    
    self.properties.key.each do |property|
      if value = first_options.delete(property.name)




        resource.send("#{property.name}=", value)
      end
    end
    
    resource.attributes = first_options.merge(create_options)
    resource.save
    resource
  end
end

get

public get(*key)

Meta Tags

See Also:

Repository#get
[View source]


640
641
642
# File 'dm-core/lib/dm-core/resource.rb', line 640

def get(*key)
  repository.get(self, key)
end

get!

public get!(key)

Meta Tags

Raises:

<ObjectNotFoundError>

"could not find .… with key: .…"

See Also:

Resource#get
[View source]


648
649
650
# File 'dm-core/lib/dm-core/resource.rb', line 648

def get!(key)
  get(key) || raise(ObjectNotFoundError, "Could not find #{self.name} with key: #{key.inspect}")
end

inheritance_property

public inheritance_property(repository_name = default_repository_name)
[View source]


633
634
635
# File 'dm-core/lib/dm-core/resource.rb', line 633

def inheritance_property(repository_name = default_repository_name)
  @properties[repository_name].inheritance_property
end

inherited

public inherited(target)
[View source]


540
541
542
543
544
545
546
547
548
549
550
551
# File 'dm-core/lib/dm-core/resource.rb', line 540

def inherited(target)
  target.instance_variable_set(:@storage_names, @storage_names.dup)
  target.instance_variable_set(:@properties, Hash.new { |h,k| h[k] = k == Repository.default_name ? self.properties(Repository.default_name).dup(target) : h[Repository.default_name].dup })
  if @relationships




    duped_relationships = {}; @relationships.each_pair{ |repos, rels| duped_relationships[repos] = rels.dup}
    target.instance_variable_set(:@relationships, duped_relationships)
  end
end

key

public key(repository_name = default_repository_name)
[View source]


629
630
631
# File 'dm-core/lib/dm-core/resource.rb', line 629

def key(repository_name = default_repository_name)
  @properties[repository_name].key
end

max

public max(*args)

Get the highest value of a property

Example

  Friend.max(:age) # returns the age of the oldest friend
  Friend.max(:age, :conditions => [ 'gender = ?', 'female' ]) # returns the age of the oldest female friends

Parameters

property<Symbol>:the property you wish to get the highest value of
opts<Hash, Symbol>:the conditions

Returns

<Integer>:return the highest value of a property given the conditions

[View source]


64
65
66
67
68
69
# File 'dm-more/dm-aggregates/lib/dm-aggregates/resource.rb', line 64

def max(*args)
  with_repository_and_property(*args) do |repository,property,options|
    check_property_is_number(property)
    repository.max(self, property, options)
  end
end

min

public min(*args)

Get the lowest value of a property

Example

  Friend.min(:age) # returns the age of the youngest friend
  Friend.min(:age, :conditions => [ 'gender = ?', 'female' ]) # returns the age of the youngest female friends

Parameters

property<Symbol>:the property you wish to get the lowest value of
opts<Hash, Symbol>:the conditions

Returns

<Integer>:return the lowest value of a property given the conditions

[View source]


43
44
45
46
47
48
# File 'dm-more/dm-aggregates/lib/dm-aggregates/resource.rb', line 43

def min(*args)
  with_repository_and_property(*args) do |repository,property,options|
    check_property_is_number(property)
    repository.min(self, property, options)
  end
end

properties

public properties(repository_name = default_repository_name)
[View source]


625
626
627
# File 'dm-core/lib/dm-core/resource.rb', line 625

def properties(repository_name = default_repository_name)
  @properties[repository_name]
end

property

public property(name, type, options = {})

defines a property on the resource

Meta Tags

Parameters:

<Symbol>

name the name for which to call this property

<Type>

type the type to define this property ass

<Hash(Symbol

> String)> options a hash of available options

[View source]


592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
# File 'dm-core/lib/dm-core/resource.rb', line 592

def property(name, type, options = {})
  property = Property.new(self, name, type, options)
  @properties[repository.name] << property

  # Add property to the other mappings as well if this is for the default
  # repository.
  if repository.name == default_repository_name




    @properties.each_pair do |repository_name, properties|
      next if repository_name == default_repository_name
      properties << property
    end
  end

  # Add the property to the lazy_loads set for this resources repository
  # only.
  # TODO Is this right or should we add the lazy contexts to all
  # repositories?
  if property.lazy?




    context = options.fetch(:lazy, :default)
    context = :default if context == true

    Array(context).each do |item|
      @properties[repository.name].lazy_context(item) << name
    end
  end

  property
end

repositories

public repositories
[View source]


621
622
623
624
625
626
# File 'dm-core/lib/dm-core/resource.rb', line 621

def repositories



  [repository] + @properties.keys.collect do |repository_name| DataMapper.repository(repository_name) end
end

repository

public repository(name = nil, &block)

Get the repository with a given name, or the default one for the current context, or the default one for this class.

Meta Tags

Parameters:

name<Symbol>

the name of the repository wanted

block<Block>

block to execute with the fetched repository as parameter

Returns:

<Object, DataMapper::Respository> whatever the block returns, if given a block, otherwise the requested repository.

[View source]


560
561
562
563
564
565
566
567
# File 'dm-core/lib/dm-core/resource.rb', line 560

def repository(name = nil, &block)
  #
  # There has been a couple of different strategies here, but me (zond) and dkubb are at least
  # united in the concept of explicitness over implicitness. That is - the explicit wish of the
  # caller (+name+) should be given more priority than the implicit wish of the caller (Repository.context.last).
  #
  DataMapper.repository(*Array(name || (Repository.context.last ? nil : default_repository_name)), &block)
end

storage_exists?

public storage_exists?(repository_name = default_repository_name)
[View source]


742
743
744
# File 'dm-core/lib/dm-core/resource.rb', line 742

def storage_exists?(repository_name = default_repository_name)
  repository(repository_name).storage_exists?(storage_name(repository_name))
end

storage_name

public storage_name(repository_name = default_repository_name)

the name of the storage recepticle for this resource. IE. table name, for database stores

Meta Tags

Returns:

<String> the storage name (IE table name, for database stores) associated with this resource in the given repository

[View source]


573
574
575
# File 'dm-core/lib/dm-core/resource.rb', line 573

def storage_name(repository_name = default_repository_name)
  @storage_names[repository_name]
end

storage_names

public storage_names

the names of the storage recepticles for this resource across all repositories

Meta Tags

Returns:

<Hash(Symbol => String)> All available names of storage recepticles

[View source]


581
582
583
584
585
586
# File 'dm-core/lib/dm-core/resource.rb', line 581

def storage_names



  @storage_names
end

sum

public sum(*args)

Get the total value of a property

Example

  Friend.sum(:age) # returns total age of all friends
  Friend.max(:age, :conditions => [ 'gender = ?', 'female' ]) # returns the total age of all female friends

Parameters

property<Symbol>:the property you wish to get the total value of
opts<Hash, Symbol>:the conditions

Returns

<Integer>:return the total value of a property given the conditions

[View source]


106
107
108
109
110
111
# File 'dm-more/dm-aggregates/lib/dm-aggregates/resource.rb', line 106

def sum(*args)
  with_repository_and_property(*args) do |repository,property,options|
    check_property_is_number(property)
    repository.sum(self, property, options)
  end
end

transaction

public transaction(&block)

Produce a new Transaction for this Resource class

Meta Tags

Returns:

<DataMapper::Adapters::Transaction a new DataMapper::Adapters::Transaction with all DataMapper::Repositories of the class of this DataMapper::Resource added.

[View source]


738
739
740
# File 'dm-core/lib/dm-core/resource.rb', line 738

def transaction(&block)
  DataMapper::Transaction.new(self, &block)
end

Protected Visibility

Protected Instance Methods Included from DataMapper::Scope

with_exclusive_scope, with_scope