2013-05-22 27 views
7

Tôi có một mô hình trong ứng dụng Rails của tôi cho Bản tin và khi được tạo, nhiều giá trị được lưu trữ trong cơ sở dữ liệu dưới dạng băm hoặc mảng được nối tiếp, để truy cập sau này. Tôi đang cố gắng tạo chế độ xem chỉnh sửa chỉ cho một trong số các băm đó, nhưng tôi không thể tìm ra cách truy cập nó trong biểu mẫu của mình.Làm thế nào để chỉnh sửa Rails serialized băm trong một hình thức?

Các băm trông như thế này khi được lưu trữ:

top_offices = { first_office: "Office Name", first_office_amount: 1234.50, 
second_office: "Office Name", second_office_amount: 1234.50 } 

Và vân vân ... có năm văn phòng.

Vì vậy, trong giao diện điều khiển tôi có thể chỉnh sửa các giá trị bằng cách làm:

bulletin = Bulletin.last 
bulletin.top_offices[:first_office] = "New Office" 
bulletin.top_offices[:first_office_amount] = 1234.00 
bulletin.save 

tôi không thể tìm ra cách để thực hiện một hình thức cho phép tôi để gán những giá trị đúng cách. Tôi thậm chí không thực sự cần hình thức để cư trú với các giá trị được lưu trữ trước đó bởi vì tôi đang thay đổi chúng hoàn toàn bất cứ lúc nào tôi sử dụng các hình thức.

Trả lời

8

Lựa chọn 1: Độc thân phương pháp dụ để cập nhật thuộc tính serialized

Theo như tôi biết nó không thể chỉnh sửa trực tiếp từ một hình thức một thuộc tính tuần tự.

Khi tôi có loại điều này, tôi luôn tạo phương pháp thể hiện trong mô hình nhận thông số và thực hiện cập nhật (Cũng có thể lưu nếu tôi kết thúc tên phương thức bằng dấu (!)).

Trong trường hợp của bạn tôi sẽ làm như sau:

class Bulletin 

    ... 

    def update_top_offices!(params) 
    params.each do |key, value| 
     self.top_offices[key] = value 
    end 

    self.save 
    end 

    ... 
end 

Phương án 2: Một getter/setter mỗi phím thuộc tính serialized

Ngoài ra một khả năng nếu bạn thực sự muốn sử dụng một hình thức để cập nhật các serialized thuộc tính là tạo một bộ thu thập/setter như sau:

class Bulletin 

    ... 

    def first_office 
    self.top_offices[:first_office] 
    end 

    def first_office=(value) 
    self.top_offices[:first_office] = value 
    end 

    ... 
end 

Nhưng sau đó đừng quên lưu các giá trị cập nhật.

Tùy chọn 3: Overriding method_missing

Một khả năng cuối cùng là ghi đè method_missing nhưng đó là một chút phức tạp hơn.

+0

OK. Tôi nghĩ rằng tôi sẽ có thể tìm ra bằng cách sử dụng tùy chọn một. Tôi có lẽ thích cách tiếp cận thứ hai nhưng tôi không thể tìm ra cách nó hoạt động trong đầu của tôi. Làm cách nào để sử dụng các phương thức đó trong biểu mẫu? Tôi có thể chỉ tạo một 'form_tag' và một số' text_field_tag' cho ': first_office' và cứ thế, khi tôi định nghĩa chúng, và gửi cho hành động cập nhật của tôi? –

+1

Trình trợ giúp xem * _field đang tìm kiếm tên thuộc tính đã cho đối tượng đã cho form_for. Vì vậy, nếu bạn đã làm 'form_for @bulletin do | f |' và sau đó bạn làm 'f.text_field: first_office' thì helper' text_field' sẽ gọi một cái gì đó có tên 'first_office' trên đối tượng.Nó có thể là một thuộc tính hoặc một phương thức. Đó là phần "ma thuật";) – ZedTuX

5

Đây là ví dụ chỉ lặp lại các cặp khóa/giá trị hiện có trong top_offices và tạo các trường biểu mẫu cho chúng.

<% @bulletin.top_offices.each do |key, value| %> 
    <input name="bulletin[top_offices][<%= key %>]" type="text" value="<%= value %>" /> 
<% end %> 

sẽ generate:

<input name="bulletin[top_offices][first_office]" ... /> 
<input name="bulletin[top_offices][first_office_amount]" ... /> 
# etc. 

Nếu bạn không tin tưởng người dùng của bạn sau đó bạn có thể muốn làm một kiểm tra sự tỉnh táo trên các giá trị nộp cho top_offices.

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