Reopening class w modelach + moduły

Hej, mam następujący problem.
korzystam z Rails 3.0.0.rc2 (ruby 1.9.2p0)

chce podzielić kod modeli w sposób bardziej modularny analogicznie do teamboxa :

w tym celu wykorzystuje reopening class. w mojej aplikacji modele są pogrupowane w moduły :

[code]- models
|

  • foo.rb
  • foo (D)
    |
    • bar.rb
    • bar (D)
      |
      • validations.rb[/code]
        kod jest następujący :

[code]models/foo.rb

module Foo
def self.table_name_prefix
‘foo_’
end
end

models/foo/bar.rb

module Foo
class Bar < ActiveRecord::Base

end
end

models/foo/bar/validations.rb

nie laduje tego pliku, nie rozszerza klasy Foo::Bar o metode foo_bar

module Foo
class Bar

def foo_bar
  'fajny string'
end

end
end[/code]
w efekcie klasa Foo::Bar nie jest rozszerzona o metodę foo_bar.
wykryłem ze ma to związek z autoloadingiem plików z katalogu models/foo/bar.

moze ktoś z Was spotkał się z podobnym problemem :wink: ?

A gdzie masz jakieś wywołanie, które by spowodowało załadowanie pliku validations? Obawiam się, że potrzebujesz starego, dobrego “require”.

AFAIR railsy ładują jakiś plik dopiero, gdy jest potrzebny. Wyjątkiem będą initializery i lib/ (dla testu wrzuć validations.rb do lib/).
Proponuję tak:

[code=ruby]models/foo/bar.rb

module Foo
class Bar < ActiveRecord::Base
# to może byc konieczne w przypadku, gdy powstaje konflikt nazw i
# modul sie nie laduje

  ActiveSupport::Dependencies.load_missing_constant self, :Validations
  include Foo::Bar::Validations

end
end

models/foo/bar/validations.rb

module Foo
module Bar::Validations
def foo_bar
‘fajny string’
end
end
end[/code]
A te prefiksy tabel, które widzę u Ciebie… czy patrzyłeś na Rails Engines?

@ Arsen7

require ‘bar/validations’ nie działa. pluje się ze nie ma pliku. probowalem rozne alternatywne formy :wink:

 LoadError: no such file to load -- bar/validations

require dziala w sytuacji gdy modele sa w drzewie o 1 poziom wyzej.

@sevos

chcialem uniknac mixinowania, a zrobic na open classess. na Teamboxie jakoś to działa, swoją drogą tam nie ma modułów, a to one rodzą problem.

Dude!

concerned with

tak to robią w teamboxie

EDIT

a co do require to może tak:

  require File.expand_path(__FILE__)+'foo/validations'

@ phocke

dzięki mistrzu, Jesteś wielki :stuck_out_tongue_winking_eye: trochę nie doczytałem teamboxowych szczegółów.

linijka w modelu

concerned_with :query, :validations

i

w initializers :

[code]class << ActiveRecord::Base
def concerned_with(*concerns)
concerns.each do |concern|
require_dependency “#{name.underscore}/#{concern}”
end
end
end

class << ActionMailer::Base
def concerned_with(*concerns)
concerns.each do |concern|
require_dependency “#{name.underscore}/#{concern}”
end
end
end[/code]