About
fv_2007
Agile innovative developer with deep insight into lots of platforms, technologies and protocols. Absolute “early adopter” in Web 2.0 technologies and more. Large professional network and eagerly talking about architecture, strategy, design patterns, restful ressources, object-oriented thinking and modeling languages such as PML. Special interest in programminglanguages constructs, knowledge on languages like Smalltalk, Erlang, Java, Clojure, Scala, Ruby... read more
Follow
Feedfavicon
Comments
Language

Mutible ActiveRecord January 09, 2008 22:17 over 2 years ago

ActiveRecord er et fint værktøj til database administration. Simpelt vedligehold eller hele migrationer af data på en enkelt eller flere databaser fra et Ruby script med ActiveRecord model objekter. Supercool!

I dette tilfælde vil jeg hente domain objekter ud fra en database og fodre dem til en anden database instans og kunne bruge alle de fede features fra active record.

Konfiguration

Første punkt er en yaml fil med database konfiguration på de forskellige databaser. I dette tilfælde operere jeg på active record objecter fra to forskellige typer af database.


database_from:
adapter: mysql

  1. encoding: utf8
    database: intra_production
    username: ****
    password: ****
    host: thor

database_to:
adapter: sqlite3
database: db/production.sqlite3
timeout: 5000

$config = YAML.load_file(File.join(File.dirname(FILE), ‘database.yml’))

Den nederste linje læser yaml konfigurationsfilen ind i ruby. Herfra kan direkte slå op i yaml strukturen.

Database forbindelse

class DBFrom < ActiveRecord::Base
  establish_connection $config['database_From']
end

class DBTo < ActiveRecord::Base
  establish_connection $config['database_To']
end

Ruby’s Mixin skal hjælpe med med at bruge de korrekte modelnavne. Jeg indkapsler modellerne i hver deres mixin modul. Det er min Separation of concern, nu kan jeg notere mine object på namespace eller prefix.

Nu mangler blot klassernedefinitionerne for de modeller der skal arbejdes med men det er nemt med AC. På grund af Ruby’s metaprogrammering egenskaber er der ingen metoder. Kun relationerne skal specificeres.

module From
  class Post < DBFrom
    has_many :comments
  end
  class Comment < DBFrom
    belongs_to :posts
  end
end

module To
  ...
end

I dette skal jeg flytte data og har derfor næsten samme skema i begge databaser men samme metoder kunne også bruges mellem development og produktion på samme skema.

posts = From::Post.find(:all, :order => "created_at")
posts.each do |post| 
    new_post = To::Post.new
    new_post.title = post.title
    new_post.save 
end

Nu har man jo naturligvis relationer til andre tabeller i databasen og de skal måske også kopieres over i den nye instans. Når jeg henter en post op er der måske nogle comments med og alle associationer skal loades samtidig.

Derpå er det blot at mixin det nye objekt og bygge de associationer som hører til. Når man kalder objektes save metode gemmes den nye record i den anden database.


By Frank Vilhelmsen - 2 tags: database ruby - Add comment