2009-02-24 24 views
43

Đá quý will_paginate bị hỏng trên phiên bản Oracle của tôi. Phương thức mặc định paginate_by_sql trong mô-đun WillPaginate đang chèn thêm 'AS' vào truy vấn và làm cho nó thất bại.Ghi đè phương thức mô-đun từ đá quý trong Rails

Bản thân mã có thể dễ dàng sửa, nhưng tôi không chắc cách nào tốt nhất để Rails nhận thay đổi của tôi.

Tôi không muốn thay đổi mã trong đá quý, vì điều đó sẽ khiến mã của tôi bị hỏng trên các máy khác.

tôi đã cố gắng tạo ra một tập tin lib/test.rb chứa:

module WillPaginate 
    def paginate_by_sql 
    (my code goes here) 
    end 
end 

và yêu cầu nó từ environment.rb, nhưng nó không nhặt thay đổi của tôi. Tôi cũng đã cố gắng yêu cầu nó từ bộ điều khiển/application.rb, nhưng một lần nữa, không chọn lên thay đổi của tôi.

Tạm thời, tôi nhận nó hoạt động bằng cách ghi đè phương pháp trong chính mô hình cụ thể, nhưng đây là một chút hack và có nghĩa là tôi không thể sử dụng nó trên bất kỳ mô hình nào khác trong dự án này.

Tôi chắc chắn có một cách dễ dàng để thực hiện việc này, nhưng tôi không có bất kỳ may mắn nào theo dõi nó bằng Google.

+0

Nếu mã đá quý bị hỏng, chắc chắn nó bị hỏng ở khắp mọi nơi? Bạn đã đăng nhập một lỗi với dự án chưa? http://wiki.github.com/mislav/will_paginate/report-bugs –

+0

Chưa - lỗi trong một trường hợp xử lý các trường hợp cụ thể. Nguyên nhân là vì tôi đang sử dụng bộ chuyển đổi oracleenhanced (chứ không phải là oracle hoặc oci). Tôi nghĩ rằng hầu hết các ppl đang sử dụng adapter oracle và sẽ không được chạy vào điều này) Sẽ được lỗi đăng nhập ngay anyway. –

Trả lời

27

gì bạn đang làm sẽ làm việc, nhưng mã của bạn cần phải trông như thế này:

module WillPaginate 
    module Finder 
    module ClassMethods 
     def paginate_by_sql(sql, options) 
     # your code here 
     end 
    end 
    end 
end 

Nói cách khác, đi vào finder.rb, xóa tất cả mọi thứ ngoại trừ các tiêu đề mô-đun và các phương pháp bạn muốn ghi đè , sau đó lưu vào một tệp trong lib và bao gồm trong environment.rb. Voila, ngay lập tức khỉ vá!

+0

Tuyệt. Cảm ơn. Điều đó đã làm các trick =) –

+13

này nên được trong initializer 'config/initializers' - không đặt này trong tập tin' environment.rb'! – Tilo

61

Một giải pháp ngắn gọn hơn:

WillPaginate::Finder::ClassMethods.module_eval do 
def paginate_by_sql sql, options 
    # Your code here 
end 
end 

Đặt mã vào một tập tin khởi tạo trong config/initializers. Đây là nơi thích hợp để đặt mã cần chạy khi môi trường được tải. Nó cũng tổ chức tốt hơn mã của bạn, làm cho ý định của mỗi tệp rõ ràng hơn, do đó các lỗi sẽ dễ dàng hơn để theo dõi. Đừng làm lộn xộn lên môi trường.rb!

+0

Trường hợp góc thú vị nếu Lớp cơ bản được tải qua 'tự động tải': http://stackoverflow.com/questions/8736451/override-a-method-inside-a-gem-from-another-gem – Tilo

+1

Khá thú vị. Trong 'paginate_by_sql' mới, tôi có thể truy cập phiên bản cũ của nó không? Tôi có thể gọi một cái gì đó như 'siêu (sql, tùy chọn)'? –

38

Ok, tôi sẽ làm điều này dễ dàng hơn cho những người như tôi, những người đến và vẫn phải vật lộn một chút sau khi đọc các câu trả lời khác.

Đầu tiên tìm ra mã mà bạn muốn thay đổi trên repo github bằng cách tìm kiếm dòng mã (bạn có thể dễ dàng tìm thấy điều này bằng pry), bạn muốn thay đổi trong các đá quý, và sau đó chọn Code trên trái thay vì Issues

enter image description here

enter image description here

Tiếp Sao chép conte nt của mô-đun bạn muốn thay đổi và đặt nó vào một tệp có tên là .rb bên trong thư mục config/initializers của bạn.Dưới đây là một ví dụ:

module Forem 
    module TopicsHelper 
    def link_to_latest_post(post) 
     text = "#{time_ago_in_words(post.created_at)} #{t("ago_by")} #{post.user}" 
     link_to text, forum_topic_path(post.topic.forum, post.topic, :anchor => "post-#{post.id}") 
    end 
    end 
end 

Bây giờ, thay đổi nó để:

Forem::TopicsHelper.module_eval do 
    def link_to_latest_post(post) 
    text = "#{time_ago_in_words(post.created_at)} #{t("ago_by")} #{post.user}" 
    link_to text, forum_topic_path(post.topic.forum, post.topic, :anchor => "post-#{post.id}") 
    end 
end 

Bây giờ, thực hiện bất kỳ thay đổi bổ sung vào mã và khởi động lại máy chủ của bạn.

Tránh bạn!

+0

Bạn có thể gọi phương thức gốc như thế này hay bạn có alias_method_chain (trong Rails anyway) cho điều đó không? – Machisuji

+0

Phương thức gốc – Abram

+1

Cảm ơn bạn @Abram! Điều này rất hữu ích! – KavitaC

Các vấn đề liên quan