Class: ActiveRecord::Base

Inherits:
Object show all
Defined in:
lib/rmtools/active_record/base.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.boolean_scopes!Object

usable to define shortcut-scopes on class with number of boolean flags: #admin, #open, #removed, etc



120
121
122
123
124
125
126
127
128
# File 'lib/rmtools/active_record/base.rb', line 120

def boolean_scopes!
  columns.select_by_type(:boolean).names.to_syms.each {|col|
    unless respond_to? col
      scope col, lambda {where "#{quoted_table_name}.#{col} = 1"}
    end
  }
  rescue
  nil
end

.declare(name, options = {}, &block) ⇒ Object



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/rmtools/active_record/declarative.rb', line 134

def declare(name, options={}, &block)
  self.table_name = name
  if !table_exists? or options[:force]
    $log < "with options[:force] the `#{table_name}` table will have been recreated each time you load the #{model_name} model" if options[:force]
    self.primary_key = options[:primary_key] if options[:id] != false and options[:primary_key]
    $log.debug "connection.create_table(#{name}, #{options.inspect}) {}"
    connection.create_table(name, options, &block)
  elsif options[:map]
    table = ConnectionAdapters::VirtualTable.new(name, connection, options[:map])
    yield table
    table.map!
  else yield ConnectionAdapters::VirtualTable.new(name, connection)
  end
  reset_column_information
end

.enum(hash) ⇒ Object

virtual (only-in-ruby) “enum” type support



104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/rmtools/active_record/base.rb', line 104

def enum hash
  key = hash.keys.first
  (self.enums ||= {}).merge! hash
  define_attribute_methods if !attribute_methods_generated?
  class_eval %{
  def #{key}
    missing_attribute('#{key}', caller) unless @attributes.has_key?('#{key}')
    self.class.enums[:#{key}][@attributes['#{key}']]
  end
  def #{key}=(val)
   write_attribute('#{key}', Fixnum === val ? val : self.class.enums[:#{key}].index val.to_s
  end
 }
end

.establish_connection_with(config) ⇒ Object



37
38
39
# File 'lib/rmtools/active_record/base.rb', line 37

def establish_connection_with config
  ActiveRecord.establish_connection_with config
end

.execute_sanitized(sql) ⇒ Object



50
51
52
# File 'lib/rmtools/active_record/base.rb', line 50

def execute_sanitized(sql)
  connection.execute sanitize_sql sql
end

.forced_create(hash) ⇒ Object

requires primary key



55
56
57
58
59
60
61
62
63
# File 'lib/rmtools/active_record/base.rb', line 55

def forced_create(hash)
  names = columns.names
  id = (hash[primary_key.to_sym] ||= maximum(primary_key)+1)
  execute_sanitized([
    "INSERT INTO #{quoted_table_name} VALUES (:#{names*', :'})", 
    Hash[names.map {|name| [name.to_sym, nil]}].merge(hash)
  ])
  find_by_sql(["SELECT * FROM #{quoted_table_name} WHERE #{primary_key} = ?", id])[0]
end

.insert_unless_exist(table, values) ⇒ Object

values must be 2-tuple array [[column1, value1], [column2, value2], …] and columns must be in order they’ve been created



66
67
68
69
70
71
72
73
74
# File 'lib/rmtools/active_record/base.rb', line 66

def insert_unless_exist(table, values)
  table = connection.quote_table_name table
  if execute_sanitized(["SELECT COUNT(*) FROM #{table} WHERE #{vaues.firsts.map {|v| "#{connection.quote_column_name v}=?"}*' AND '} LIMIT 1", *values.lasts]).to_a.flatten > 0
    false
  else
    execute_sanitized ["INSERT INTO #{table} VALUES (#{['?']*values.size*','})", *values.lasts]
    true
  end
end

.merge_conditions(*conditions) ⇒ Object



41
42
43
44
45
46
47
48
# File 'lib/rmtools/active_record/base.rb', line 41

def merge_conditions(*conditions)
  segments = conditions.map {|condition| 
    sanitize_sql condition
  }.reject {|condition|
    condition.blank?
  }
  "(#{segments.join(') AND (')})" unless segments.empty?
end

.non_null_scopes!Object

more universal version of boolean_scopes! that helps to find records with any non-null values, including zero and empty string



132
133
134
135
136
137
138
139
140
141
# File 'lib/rmtools/active_record/base.rb', line 132

def non_null_scopes!
  boolean_scopes!
  columns.select_null.names.to_syms.each {|col|
    unless respond_to? col
      scope col, lambda {where "#{quoted_table_name}.#{col} is not null"}
    end
  }
rescue
  nil
end

.select_rand(limit, options = {}) ⇒ Object



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
# File 'lib/rmtools/active_record/base.rb', line 76

def select_rand(limit, options={})
  cnt = options.delete :cnt
  _where = options.delete :where
  cnt_where = options.delete(:cnt_where) || _where
  if !cnt and !cnt_where
    ids = options[:ids] || pluck(:id)
    if fields = options[:fields]
      return select(fields).where(id: ids.randsample(limit)).all
    else
      return where(id: ids.randsample(limit)).all
    end
    #cnt = options[:ids].size
    #where ||= "#{table_name}.id IN (:ids)"
  end
  discnt = options.delete :discnt
  tables = options.delete(:tables) || table_name
  cnt_tables = options.delete(:cnt_tables) || tables
  fields = (options.delete(:fields) || %w[*])*','
  
  find_by_sql(["SELECT * FROM (
      SELECT @cnt:=#{cnt ? cnt.to_i : 'COUNT(*)'}+1#{-discnt.to_i if discnt}, @lim:=#{limit.to_i}#{" FROM #{cnt_tables} WHERE #{cnt_where}" if !cnt}
    ) vars
    STRAIGHT_JOIN (
      SELECT #{fields}, @lim:=@lim-1 FROM #{tables} WHERE #{"(#{_where}) AND " if _where} (@cnt:=@cnt-1) AND RAND() < @lim/@cnt
    ) i", options])
end

Instance Method Details

#delete(field = nil) ⇒ Object

by default model.delete() and model.destroy() won’t work if model has no id



163
164
165
166
167
168
169
# File 'lib/rmtools/active_record/base.rb', line 163

def delete(field=nil)
  id ? 
    delete_with_id : 
    field ? 
      self.class.delete_all(field => self[field]) : 
      self.class.delete_all(attributes)
end

#delete_with_idObject



160
# File 'lib/rmtools/active_record/base.rb', line 160

alias :delete_with_id :delete

#destroy(field = nil) ⇒ Object



171
172
173
174
175
176
177
# File 'lib/rmtools/active_record/base.rb', line 171

def destroy(field=nil)
  id ? 
    destroy_with_id : 
    field ? 
      self.class.destroy_all(field => self[field]) : 
      self.class.destroy_all(attributes)
end

#destroy_with_idObject



161
# File 'lib/rmtools/active_record/base.rb', line 161

alias :destroy_with_id :destroy

#resource_pathObject



179
180
181
# File 'lib/rmtools/active_record/base.rb', line 179

def resource_path
  "#{self.class.name.tableize}/#{id}"
end

#to_hashObject

fix for thinking_sphinx equation in #instances_from_class: ids.collect {|obj_id| instances.detect do |obj| obj.primary_key_for_sphinx == obj_id end} where obj_id is Array def primary_key_for_sphinx

[read_attribute(self.class.primary_key_for_sphinx)]

end



152
153
154
155
156
157
158
# File 'lib/rmtools/active_record/base.rb', line 152

def to_hash
  return attributes if respond_to? :attributes
  serializer = Serializer.new(self)
  serializer.respond_to?(:attributes_hash) ?
    serializer.attributes_hash : 
    serializer.serializable_record
end

#update_attributes?(hash) ⇒ Boolean

Returns:

  • (Boolean)


187
188
189
190
# File 'lib/rmtools/active_record/base.rb', line 187

def update_attributes?(hash)
  hash.each {|k, v| self[k] = v}
  changed? && save
end

#with_same(attr) ⇒ Object



183
184
185
# File 'lib/rmtools/active_record/base.rb', line 183

def with_same(attr)
  self.class.where(attr => self[attr])
end