Ai đó có thể giải thích bộ sưu tập với tôi bằng những thuật ngữ đơn giản, rõ ràng không?


146

Tôi đang xem qua các tài liệu API của Rails collection_selectvà chúng thật tuyệt vời.

Tiêu đề là đây:

collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})

Và đây là mã mẫu duy nhất họ đưa ra:

collection_select(:post, :author_id, Author.all, :id, :name_with_initial, :prompt => true)

Ai đó có thể giải thích, bằng cách sử dụng một liên kết đơn giản (giả sử Userhas_many Plansvà a Planthuộc về a User), những gì tôi muốn sử dụng trong cú pháp và tại sao?

Chỉnh sửa 1: Ngoài ra, sẽ thật tuyệt vời nếu bạn giải thích cách thức hoạt động bên trong một form_helperhoặc một hình thức thông thường. Hãy tưởng tượng bạn đang giải thích điều này cho một nhà phát triển web hiểu về phát triển web, nhưng 'tương đối mới' với Rails. Làm thế nào bạn sẽ giải thích nó?


50
Đúng. Đó là tài liệu khủng khiếp nhất tôi từng thấy
Jaseem

1
Công bằng mà nói, tài liệu này khá ổn, không phải trong FormBuildernhưng trong FormOptionsHelper: api.rubyonrails.org/groupes/ActionView/Helpers/ Lỗi
amiuhle

1
Phần yêu thích của tôi là khi bạn sử dụng bộ sưu tập trong một biểu mẫu và thay đổi toàn bộ chữ ký để đối tượng không phải là một phần của danh sách tham số mà thay vào đó, bộ sưu tập được gọi là phương thức trên đối tượng. Đừng nghĩ rằng họ đề cập đến điều đó trong các tài liệu ...
user3670743

1
Đây là một dự án nguồn mở: nếu tài liệu kém, chúng ta chỉ có bản thân mình để đổ lỗi; thật tuyệt vời nếu chỉ có chúng tôi sẽ làm hết sức mình để làm cho nó tốt hơn. PR nhỏ / đơn giản đi một chặng đường dài.
BKSpurgeon

Câu trả lời:


305
collection_select(
    :post, # field namespace 
    :author_id, # field name
    # result of these two params will be: <select name="post[author_id]">...

    # then you should specify some collection or array of rows.
    # It can be Author.where(..).order(..) or something like that. 
    # In your example it is:
    Author.all, 

    # then you should specify methods for generating options
    :id, # this is name of method that will be called for every row, result will be set as key
    :name_with_initial, # this is name of method that will be called for every row, result will be set as value

    # as a result, every option will be generated by the following rule: 
    # <option value=#{author.id}>#{author.name_with_initial}</option>
    # 'author' is an element in the collection or array

    :prompt => true # then you can specify some params. You can find them in the docs.
)

Hoặc ví dụ của bạn có thể được trình bày dưới dạng mã sau:

<select name="post[author_id]">
    <% Author.all.each do |author| %>
        <option value="<%= author.id %>"><%= author.name_with_initial %></option>
    <% end %>
</select>

Đây không phải là tài liệu trong FormBuilder, nhưng trongFormOptionsHelper


32
Điều này thật dễ dàng, một trong những giải thích tốt nhất về cấu trúc Rails phức tạp mà tôi đã thấy. Bạn đã sử dụng ngôn ngữ rõ ràng, cùng với các cấu trúc Rails cơ bản để củng cố nó. Cảm ơn nhiều!!
marcamillion

2
Tại sao bạn lại đặt tên cho nó là "post [Author_id]"?
Jaseem

@alexkv cảm ơn bạn - bạn có thể giải thích về tầm quan trọng của: post, # không gian tên trường và: Author_id, # tham số tên trường (hai cái đầu tiên) - Tôi không hiểu mục đích của chúng trong sơ đồ của mọi thứ - có thể ' Họ có bị bỏ qua không?
BKSpurgeon

1
Các param đầu tiên thực sự có thể là con số không. Nếu bạn đang tạo một biểu mẫu đối tượng, nó sẽ là đối tượng đó để lựa chọn có cùng không gian tên với phần còn lại của biểu mẫu. Nếu điều đó là không cần thiết, hãy để số 1 là con số không. Cái thứ 2 là tên của điều khiển, vì vậy nếu nó cập nhật một trường trên một đối tượng (tham số thứ 1) thì tên trường là tham số thứ hai. Nếu bạn đang tạo một số biểu mẫu cho các mục đích sử dụng khác, tham số thứ 2 là bất cứ điều gì bạn muốn điều khiển biểu mẫu được đặt tên và id'd. Tại sao sử dụng cái này với số 1? Có lẽ bởi vì bạn muốn Collection_select cho các tùy chọn: prompt.
elc

1
Tôi cũng cần lưu ý rằng bạn có thể nhận được hiệu ứng tương tự khi xử lý tham số nhanh chóng trên select_tag bằng cách sử dụng tùy chọn_for_select, có thể sẽ trả lời giống như một bộ sưu tập với một đối tượng không.
elc

21

Bản thân tôi đã dành khá nhiều thời gian cho các hoán vị của các thẻ chọn.

collection_selectxây dựng một thẻ chọn từ một bộ sưu tập các đối tượng. Giữ điều này trong tâm trí,

object: Tên của đối tượng. Điều này được sử dụng để tạo tên của thẻ và được sử dụng để tạo giá trị được chọn. Đây có thể là một đối tượng thực tế hoặc một ký hiệu - trong trường hợp sau, biến thể hiện của tên đó được tìm kiếm trong liên kết củaActionController (nghĩa là :posttìm một var thể hiện được gọi @posttrong trình điều khiển của bạn.)

method: Tên của phương thức. Điều này được sử dụng để tạo tên của thẻ .. Nói cách khác, thuộc tính của đối tượng bạn đang cố gắng lấy từ lựa chọn

collection : Bộ sưu tập đồ vật

value_method : Đối với mỗi đối tượng trong bộ sưu tập, phương thức này được sử dụng cho giá trị

text_method : Đối với mỗi đối tượng trong bộ sưu tập, phương thức này được sử dụng để hiển thị văn bản

Thông số tùy chọn:

options: Tùy chọn mà bạn có thể vượt qua. Đây là những tài liệu ở đây , dưới tiêu đề Tùy chọn.

html_options: Bất cứ điều gì được thông qua ở đây, chỉ cần thêm vào thẻ html được tạo. Nếu bạn muốn cung cấp một lớp, id hoặc bất kỳ thuộc tính nào khác, nó sẽ xuất hiện ở đây.

Hiệp hội của bạn có thể được viết là:

collection_select(:user, :plan_ids, Plan.all, :id, :name, {:prompt => true, :multiple=>true })

Liên quan đến việc sử dụng form_for, một lần nữa với các thuật ngữ rất đơn giản, cho tất cả các thẻ có trong form_for, ví dụ. f.text_field, bạn không cần cung cấp objecttham số ( ) đầu tiên . Điều này được lấy từ form_forcú pháp.


2
Cảm ơn vì đã dành thời gian ... vấn đề duy nhất là, trong tất cả sự trung thực, lời giải thích của bạn không giúp làm rõ mọi thứ trong đầu tôi. Bạn đã sử dụng rất nhiều thuật ngữ trong định nghĩa thực tế. Tôi đánh giá cao bạn dành thời gian mặc dù vậy - vì vậy, tôi đã bỏ phiếu cho nó.
marcamillion

4
Vì những lý do được tuyên bố rõ ràng bởi marcamillion, tôi đã bỏ phiếu cho nó.
Jamie
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.