EDIT: Để đạt được chính xác những gì bạn đang tìm kiếm ở trên, bạn muốn sử dụng này để ghi đè các setter mặc định trong file mô hình của bạn:
def path=(value)
self[:path] = connection.execute("SELECT text2ltree('#{value}');")[0][0]
end
Sau đó mã bạn có trên hoạt động.
Tôi quan tâm đến việc tìm hiểu thêm về nội bộ ActiveRecord và nền tảng lập trình meta không thể xuyên thấu của nó, vì vậy tôi đã cố gắng hoàn thành những gì bạn đã mô tả trong phần bình luận bên dưới. Dưới đây là một ví dụ mà làm việc cho tôi (đây là tất cả trong post.rb):
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
điều khiển đầu ra:
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>
Trong cuộc sống thực tôi đoán bạn muốn include
module trong ActiveRecord: : Cơ sở, trong một tệp ở đâu đó trước đó trong đường dẫn tải. Bạn cũng phải xử lý đúng kiểu đối số mà bạn đang chuyển sang hàm cơ sở dữ liệu. Cuối cùng, tôi đã biết rằng connection.execute
được thực hiện bởi mỗi bộ điều hợp cơ sở dữ liệu, vì vậy cách bạn truy cập kết quả có thể khác trong Postgres (ví dụ này là SQLite3, trong đó tập kết quả được trả về dưới dạng mảng băm và khóa cho bản ghi dữ liệu đầu tiên . là 0]
bài viết trên blog này là vô cùng hữu ích:
http://www.fakingfantastic.com/2010/09/20/concerning-yourself-with-active-support-concern/
như là Rails hướng dẫn cho plugin-authoring:
http://guides.rubyonrails.org/plugins.html
Ngoài ra, đối với những gì nó có giá trị, tôi nghĩ rằng trong Postgres tôi vẫn làm điều này bằng cách sử dụng một di chuyển để tạo ra một truy vấn viết lại quy tắc, nhưng điều này làm cho một kinh nghiệm học tập tuyệt vời. Hy vọng nó hoạt động và tôi có thể ngừng suy nghĩ về cách làm điều đó ngay bây giờ.
Bạn có thể viết một hàm Postgres (thủ tục lưu sẵn) và sau đó chỉ cần gọi 'SELECT myfunc ('1.2.3')'. Tôi có thể cung cấp một ví dụ nếu bạn quan tâm đến tuyến đường đó. –