EDIT: Aby dokładnie to, czego szukasz powyżej osiągnąć, można to wykorzystać, aby zastąpić domyślny setter w pliku modelu:
def path=(value)
self[:path] = connection.execute("SELECT text2ltree('#{value}');")[0][0]
end
Następnie kod masz powyżej działa.
Chciałbym dowiedzieć się więcej o wewnętrznych elementach ActiveRecord i ich nieprzenikalnych podstawach metaprogramowania, więc jako ćwiczenie próbowałem osiągnąć to, co opisałeś w swoich komentarzach poniżej. Oto przykład, który pracował dla mnie (to wszystko w post.rb): wyjście
module DatabaseTransformation
extend ActiveSupport::Concern
module ClassMethods
def transformed_by_database(transformed_attributes = {})
transformed_attributes.each do |attr_name, transformation|
define_method("#{attr_name}=") do |argument|
transformed_value = connection.execute("SELECT #{transformation}('#{argument}');")[0][0]
write_attribute(attr_name, transformed_value)
end
end
end
end
end
class Post < ActiveRecord::Base
attr_accessible :name, :path, :version
include DatabaseTransformation
transformed_by_database :name => "length"
end
konsoli:
1.9.3p194 :001 > p = Post.new(:name => "foo")
(0.3ms) SELECT length('foo');
=> #<Post id: nil, name: 3, path: nil, version: nil, created_at: nil, updated_at: nil>
W prawdziwym życiu przypuszczam że chcesz include
moduł w ActiveRecord: : Base, w pliku gdzieś wcześniej w ścieżce ładowania. Musiałbyś również poprawnie obsługiwać typ argumentu, który przekazujesz do funkcji bazy danych. Na koniec dowiedziałem się, że connection.execute
jest implementowany przez każdą kartę baz danych, więc sposób uzyskiwania dostępu do wyniku może być inny w PostgreSQL (ten przykład to SQLite3, gdzie zestaw wyników jest zwracany jako tablica skrótów i klucz do pierwszego rekordu danych . jest 0]
Ten blog post był niezwykle pomocny:
http://www.fakingfantastic.com/2010/09/20/concerning-yourself-with-active-support-concern/
jak było prowadnicami dla plugin-authoring:
http://guides.rubyonrails.org/plugins.html
Ponadto, w moim przekonaniu, w Postgres nadal robiłbym to za pomocą migracji, aby utworzyć regułę przepisywania zapytań, ale dzięki temu można się było nauczyć. Mam nadzieję, że to działa i mogę przestać myśleć o tym, jak to zrobić teraz.
Możesz napisać funkcję PostgreS (procedura składowana), a następnie po prostu wywołać 'SELECT myfunc ('1.2.3')'. Mogę podać przykład, jeśli jesteś zainteresowany tą trasą. –