2013-08-21 28 views
5

Active Record Store cho phép bạn tuần tự hóa các tham số bên trong một ô đơn lẻ.Trình truy cập cửa hàng động đang hoạt động dựa trên biểu mẫu người dùng?

I.e.

class User < ActiveRecord::Base 
    store :options, accessors: [ :option1, :option2, :another_random_option ] 
end 

Tất cả các trình truy cập được tuần tự hóa trong cột "tùy chọn" của bảng người dùng ngay bây giờ.

u = User.new 
u.option2 = 'some option' 
u.option2 # => 'some option' 

này hoạt động tuyệt vời cho ứng dụng của tôi bởi vì tôi có để tạo ra nhiều hình thức trên một cơ sở hàng ngày, nơi 90% dưới hình thức là như nhau (username, sở thích, sở thích, vv) và sau đó 10% là schema -Không (random_option_here, another_random_option_in_another_form). Tôi cũng không bao giờ cần sắp xếp theo các tùy chọn lược đồ-ít.

Tôi đã tạo 1 bảng cho 90% trường biểu mẫu luôn giống nhau và sau đó tôi có một bảng khác với 10% trường cuối cùng (lý do tôi có bảng khác là vì điều này là mối quan hệ thuộc tính, vì vậy người dùng có thể có nhiều hàng trong bảng này).

<%= form_tag do %> 
    <%= #render partial form for an object that has non-changing fields %> 
    ... 
    <%= #render a schema-less partial form based off an ID passed here %> 
<% end > 

Bây giờ vấn đề duy nhất là mỗi khi tôi tạo ra một lĩnh vực mới trong hình thức tùy chỉnh, tôi phải thêm tham số đó để Active Record Store accessors, nếu không tôi có được một phương pháp thiếu lỗi. Nó sẽ là tốt đẹp nếu tôi chỉ có thể đi vào và tạo ra nhiều dạng xem như tôi muốn cho các trường lược đồ-ít hơn và không bao giờ cập nhật các accessors trong Model. Vì vậy, câu hỏi của tôi là: Có cách nào để tự động thêm tất cả các trường tùy chỉnh đã gửi của người dùng vào mảng truy cập, theo cách đó nếu người dùng gửi trường "some_random_option1221", "another_option_here" thì tôi không phải đi sâu vào accessors array và thêm trường đó?

Cảm ơn!

Trả lời

11

Với đường ray 4 và postgresql các công trình sau đây cho tôi. Dường như với một số chỉnh sửa nhỏ các đường ray 3 phương pháp lưu trữ cũng có thể được sử dụng.

Gọi store_accessor động trên mỗi khóa trường trong mã băm cửa hàng thuộc sở hữu của một phiên bản mẫu cụ thể. Nếu bạn có một mô hình User với một cột có tên là các tùy chọn kiểu hstore, thì bạn đã có thể truy cập vào hash tùy chọn. (Trong đường ray 3, bạn sẽ gọi phương thức lưu trữ như trong mã trong câu hỏi của bạn để làm cho phương thức tùy chọn hoạt động.)

Tạo phương pháp để làm điều này bất cứ khi nào giao diện người dùng của bạn thêm trường mới. Sau đó, cũng gọi phương thức này after_initialize để tải một người dùng từ db sẽ thiết lập các trình truy cập tên trường tại thời điểm tải. Bạn cũng có thể muốn gọi phương thức này là after_save.

class User < ActiveRecord::Base 
    after_initialize :add_field_accessors 
    after_save  :add_field_accessors 

    def add_store_accessor field_name 
    singleton_class.class_eval {store_accessor :options, field_name} 
    end 

    def add_field_accessors 
    num_fields = options.try(:keys).try(:count) || 0 
    options.keys.each {|field_name| add_store_accessor field_name} if num_fields > 0 
    end 
end 

Sau đó, mỗi cá thể người dùng có thể có các phương pháp store_accessor khác nhau tùy thuộc vào trường nào mỗi người dùng có trong cột tùy chọn trong hàng db cho người dùng đó.

Trong bộ điều khiển, tùy thuộc vào giao diện người dùng ưa thích của bạn để thêm/xóa/chỉnh sửa tùy chọn, bạn có thể có phương pháp trợ giúp để xây dựng các tùy chọn trên người dùng và gọi nó từ mới, tạo, cập nhật, v.v.

def build_options 
    @user.options = options_hash 
    @user.add_field_accessors 
end 

Trong đường ray 3, thay vì gọi store_accessor, bạn sẽ gọi attr_accessor. Lưu ý rằng bạn sẽ không thể gọi User.new (: option_1 => 'some_option_value') vì đối tượng lớp User không có phương thức accessor (vì mỗi cá thể người dùng có thể có các thuộc tính khác nhau.)

+0

Rất tuyệt, có vẻ như '' num_fields = options.try (: keys) .ry (: count) || 0'' là không cần thiết, bạn có thể thêm một giá trị mặc định '' {} '' vào các trường tùy chọn, vì vậy options.keys chỉ là một mảng trống. – zw963

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