Module: ActiveRecord::Has::CustomFields::InstanceMethods::ClassMethods

Defined in:
lib/has_custom_fields.rb

Instance Method Summary collapse

Instance Method Details

#create_attribute_table(options = {}) ⇒ Object

Rake migration task to create the versioned table using options passed to has_custom_fields



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
# File 'lib/has_custom_fields.rb', line 213

def create_attribute_table(options = {})
  options = custom_field_options[self.name]
  klass = Object.const_get(options[:fields_class_name])
  return if connection.tables.include?(options[:values_table_name])

  # todo: get the real pkey type and name
  scope_fkeys = options[:scopes].collect{|s| "#{s.to_s}_id"}
  
  ActiveRecord::Base.transaction do
  
    self.connection.create_table(options[:fields_table_name], options) do |t|
      t.string options[:name_field], :null => false, :limit => 63
      t.string :style, :null => false, :limit => 15
      t.string :select_options
      scope_fkeys.each do |s|
        t.integer s
      end
      t.timestamps
    end
    self.connection.add_index options[:fields_table_name], scope_fkeys + [options[:name_field]], :unique => true, 
      :name => "#{options[:fields_table_name]}_unique_index"
  
    # add foreign keys for scoping tables
    options[:scopes].each do |s|
      self.connection.execute <<-FOO
        alter table #{options[:fields_table_name]}
          add foreign key (#{s.to_s}_id)
          references
          #{eval(s.to_s.classify).table_name}(#{eval(s.to_s.classify).primary_key})
      FOO
    end
    
    # add xor constraint
    if !options[:scopes].empty? 
      self.connection.execute <<-FOO
        alter table #{options[:fields_table_name]} add constraint scopes_xor check
          (1 = #{options[:scopes].collect{|s| "(#{s.to_s}_id is not null)::integer"}.join(" + ")})
      FOO
    end
    
    self.connection.create_table(options[:values_table_name], options) do |t|
      t.integer options[:foreign_key], :null => false
      t.integer options[:fields_table_name].singularize.foreign_key, :null => false
      t.string options[:value_field], :null => false
      t.timestamps
    end
    
    self.connection.add_index options[:values_table_name], options[:foreign_key]
    self.connection.add_index options[:values_table_name], options[:fields_table_name].singularize.foreign_key
    
    self.connection.execute <<-FOO
      alter table #{options[:values_table_name]} 
      add foreign key (#{options[:fields_table_name].singularize.foreign_key})
      references #{options[:fields_table_name]}(#{eval(options[:fields_class_name]).primary_key})
    FOO
  end
end

#drop_attribute_table(options = {}) ⇒ Object

Rake migration task to drop the attribute table



274
275
276
277
# File 'lib/has_custom_fields.rb', line 274

def drop_attribute_table(options = {})
  options = custom_field_options[self.name]
  self.connection.drop_table options[:values_table_name]
end

#drop_field_table(options = {}) ⇒ Object



279
280
281
282
# File 'lib/has_custom_fields.rb', line 279

def drop_field_table(options = {})
  options = custom_field_options[self.name]
  self.connection.drop_table options[:fields_table_name]
end