Mô hình Rails, Chế độ xem, Bộ điều khiển và Trình trợ giúp: đi đâu?


155

Trong Ruby on Rails Development (hay nói chung là MVC), tôi nên tuân theo quy tắc nhanh nào là đặt logic ở đâu.

Vui lòng trả lời trong câu khẳng định - Với Do hãy đặt cái này ở đây , thay vì đừng đặt nó ở đó .

Câu trả lời:


173

MVC

Trình điều khiển : Đặt mã ở đây có liên quan đến việc tìm ra những gì người dùng muốn và quyết định những gì sẽ cung cấp cho họ, tìm hiểu xem họ đã đăng nhập chưa, liệu họ có nên xem dữ liệu nhất định hay không, v.v ... Cuối cùng, bộ điều khiển xem xét các yêu cầu và tìm ra dữ liệu nào (Mô hình) để hiển thị và Chế độ xem sẽ hiển thị. Nếu bạn nghi ngờ về việc liệu mã có nên đi vào bộ điều khiển hay không, thì có lẽ không nên. Giữ bộ điều khiển của bạn gầy .

Chế độ xem : Chế độ xem chỉ nên chứa mã tối thiểu để hiển thị dữ liệu của bạn (Kiểu), không nên xử lý hoặc tính toán nhiều, nên hiển thị dữ liệu được tính toán (hoặc tóm tắt) bởi Mô hình hoặc được tạo từ Bộ điều khiển. Nếu Chế độ xem của bạn thực sự cần xử lý mà Mô hình hoặc Bộ điều khiển không thể thực hiện, hãy đặt mã vào Trình trợ giúp. Rất nhiều mã Ruby trong Chế độ xem làm cho các trang đánh dấu khó đọc.

Mô hình : Mô hình của bạn phải là nơi tất cả mã của bạn liên quan đến dữ liệu của bạn (các thực thể tạo nên trang web của bạn, ví dụ như Người dùng, Bài đăng, Tài khoản, Bạn bè, v.v.). Nếu mã cần lưu, cập nhật hoặc tóm tắt dữ liệu liên quan đến các thực thể của bạn, hãy đặt nó ở đây. Nó sẽ được sử dụng lại trên Lượt xem và Bộ điều khiển của bạn.


2
Mọi người đang bắt đầu di chuyển ra khỏi mô hình chất béo. Tôi thích nghĩ về mô hình của tôi như là một cấu trúc dữ liệu. Sau đó, tôi viết một số đối tượng Ruby thực hiện hành vi, khởi tạo nó bằng mô hình (nó xử lý mô hình như dữ liệu của nó giống như cách bạn có thể coi chuỗi và mảng là dữ liệu trong các đối tượng bên ngoài Rails). Đây là một video tốt với một ví dụ về kỹ thuật này.
Joshua Cheek

@AdamDonahue Tôi không chắc chắn bất cứ điều gì chất béo có thể được coi là một điều tốt. Các trách nhiệm tốt hơn là thuộc về các dịch vụ.
fatuhoku 8/12/2016

35

Để thêm vào câu trả lời của pauliephonic:

Trình trợ giúp : các chức năng để tạo chế độ xem dễ dàng hơn. Ví dụ: nếu bạn luôn lặp đi lặp lại một danh sách các vật dụng để hiển thị giá của chúng, hãy đặt nó vào một trình trợ giúp (cùng với một phần cho màn hình thực tế). Hoặc nếu bạn có một phần của RJS mà bạn không muốn làm lộn xộn khung nhìn, hãy đặt nó vào một trình trợ giúp.


Trên thực tế, chúng ta cũng không đặt phương thức sign_in trong Helper? Như Hướng dẫn RoR đã đề xuất ở đây >>> ruby.ra Whileutorial.org/book/ từ
Ivan Wang

14

Mẫu MVC thực sự chỉ liên quan đến UI và không có gì khác. Bạn không nên đặt bất kỳ logic kinh doanh phức tạp nào trong bộ điều khiển vì nó kiểm soát khung nhìn nhưng không phải logic. Bộ điều khiển nên quan tâm đến việc chọn chế độ xem phù hợp và ủy thác các nội dung phức tạp hơn cho mô hình miền (Mô hình) hoặc lớp doanh nghiệp.

Domain Driven Design có một khái niệm về Dịch vụ là nơi bạn gắn logic, cần phối hợp một số loại đối tượng khác nhau, thường có nghĩa là logic không thuộc về lớp Model một cách tự nhiên.

Tôi thường nghĩ về lớp Dịch vụ là API của các ứng dụng của mình. Các lớp Dịch vụ của tôi thường ánh xạ khá sát với các yêu cầu của ứng dụng mà tôi đang tạo, do đó, lớp Dịch vụ hoạt động như một sự đơn giản hóa các tương tác phức tạp hơn được tìm thấy ở các cấp thấp hơn của ứng dụng của tôi, tức là bạn có thể hoàn thành mục tiêu tương tự bỏ qua các lớp Dịch vụ nhưng bạn phải kéo thêm nhiều đòn bẩy để làm cho nó hoạt động.

Lưu ý rằng tôi không nói về Rails ở đây Tôi đang nói về một phong cách kiến ​​trúc chung giải quyết vấn đề cụ thể của bạn.


Đây là một câu trả lời tuyệt vời :)
Carlos Martinez



7

Không đặt những thứ liên quan đến ủy quyền / kiểm soát truy cập trong bộ điều khiển.

Mô hình là tất cả về dữ liệu của bạn. Xác nhận, Mối quan hệ, CRUD, Logic kinh doanh

Lượt xem là về việc hiển thị dữ liệu của bạn. Chỉ hiển thị và nhận đầu vào.

Bộ điều khiển là về việc kiểm soát dữ liệu nào đi từ mô hình của bạn đến chế độ xem của bạn (và chế độ xem nào) và từ chế độ xem của bạn đến mô hình của bạn. Bộ điều khiển cũng có thể tồn tại mà không cần mô hình.

Tôi thích nghĩ về bộ điều khiển như một nhân viên bảo vệ / nhân viên tiếp tân hướng dẫn khách hàng (yêu cầu) của bạn đến quầy thích hợp nơi bạn hỏi một giao dịch viên (xem) một câu hỏi. Người giao dịch (xem) sau đó đi và nhận được câu trả lời từ người quản lý (người mẫu), người mà bạn không bao giờ nhìn thấy. Sau đó, bạn yêu cầu quay lại nhân viên bảo vệ / nhân viên tiếp tân (người điều khiển) và đợi cho đến khi bạn được hướng dẫn đi một người giao dịch khác (người xem), người sẽ cho bạn biết câu trả lời mà người quản lý (người mẫu) đã trả lời họ để trả lời câu hỏi của người giao dịch khác .

Tương tự như vậy nếu bạn muốn nói với người giao dịch (xem) một cái gì đó thì phần lớn điều tương tự xảy ra ngoại trừ người giao dịch thứ hai sẽ cho bạn biết liệu người quản lý có chấp nhận thông tin của bạn hay không. Cũng có thể nhân viên bảo vệ / nhân viên tiếp tân (bộ điều khiển) có thể đã bảo bạn đi bộ vì bạn không được phép thông báo cho người quản lý thông tin đó.

Vì vậy, để mở rộng phép ẩn dụ, trong thế giới rập khuôn và phi thực tế của tôi, người nói (quan điểm) rất đẹp nhưng trống rỗng và thường tin bất cứ điều gì bạn nói với họ, nhân viên bảo vệ / nhân viên tiếp tân rất lịch sự nhưng không hiểu biết nhưng họ biết mọi người nên ở đâu không nên đi và các nhà quản lý thực sự xấu xí và xấu tính nhưng biết tất cả mọi thứ và có thể nói điều gì là đúng và điều gì không.


4

Một điều giúp phân tách đúng cách là tránh kiểu "vượt qua các biến cục bộ từ trình điều khiển để xem" mô hình chống. Thay vì điều này:

# app/controllers/foos_controller.rb:
class FoosController < ApplicationController

  def show
    @foo = Foo.find(...)
  end

end

#app/views/foos/show.html.erb:
...
<%= @foo.bar %>
...

Hãy thử di chuyển nó đến một getter có sẵn như là một phương thức trợ giúp:

# app/controllers/foos_controller.rb:
class FoosController < ApplicationController

  helper_method :foo

  def show
  end

  protected

  def foo
    @foo ||= Foo.find(...)
  end

end

#app/views/foos/show.html.erb:
...
<%= foo.bar %>
...

Điều này giúp dễ dàng sửa đổi những gì được đưa vào "@foo" và cách sử dụng. Nó làm tăng sự tách biệt giữa bộ điều khiển và khung nhìn mà không làm cho chúng phức tạp hơn.


ừm ... Yuk. Bạn có thể vui lòng thêm một số lý do / kịch bản tốt khi bạn sẽ làm điều này. Điều này phá vỡ KISS và YAGNI và rất nặng mùi (chỉ cần ném thêm một sáo ngữ nữa)
Sixty4Bit

2
1) Rails thực hiện rất nhiều phép thuật để sao chép các biến đối tượng của trình điều khiển vào đối tượng xem của bạn. 2) Việc triển khai được đề xuất cũng chỉ tải foo nếu được truy cập, điều này có thể giúp tiết kiệm một số công việc. Câu trả lời quan trọng thực sự là 1), mặc dù.
webmat

11
Thở dài này thật kinh khủng. Chia sẻ biến đối tượng Rails là một tính năng không phải là mô hình chống. Đó là một loại đường cú pháp phổ biến, có tinh thần thấp mà hiếm khi gây ra các vấn đề trong thế giới thực. Nếu bạn không thích nó, tốt thôi, nhưng mã hóa xung quanh nó với cấu trúc phi tiêu chuẩn baroque làm cho mọi thứ trở nên vô cùng tồi tệ. Trong trường hợp này, bạn đang thực sự biến foo thành một biến toàn cục (trên mỗi bộ điều khiển). Cố gắng sửa chữa một sự lạm dụng nhận thức của phạm vi biến bằng cách tăng đáng kể phạm vi là vô cùng mỉa mai.
gtd

1
Tôi không mua nó, dasil003. Phạm vi của foo@foogiống nhau - cả hai đều nằm trong phạm vi của cặp <ControllerClass, request>. Ngoài ra, bằng cách sử dụng phiên bản getter, tôi có thể thay đổi cách Footìm thấy / lưu trữ / lưu trữ đối tượng đó mà không thay đổi cách xem truy cập vào nó.
James A. Rosen

1
Tôi nghĩ bạn có nghĩa là "vượt qua các biến đối tượng". Một var thể hiện sẽ rò rỉ trạng thái cho toàn bộ kết xuất, ngay cả trong các phần được lồng sâu. Giải pháp của bạn cũng bị rò rỉ trạng thái, nhưng tốt hơn một chút so với var vì nó không cho phép gán lại. Vượt qua một địa phương thực sự là tốt nhất bởi vì nó giống như gọi một phương thức; địa phương không thể được nhìn thấy bởi các hạt. Xem câu trả lời này .
Kelvin

2

Chà, nó phụ thuộc vào logic phải xử lý ...

Thông thường, sẽ rất hợp lý khi đẩy nhiều thứ hơn vào các mô hình của bạn, để lại các bộ điều khiển nhỏ. Điều này đảm bảo rằng logic này có thể dễ dàng được sử dụng từ bất cứ nơi nào bạn cần để truy cập dữ liệu mà mô hình của bạn đại diện. Lượt xem nên chứa hầu như không có logic. Vì vậy, thực sự, nói chung, bạn nên cố gắng làm cho nó để bạn không lặp lại chính mình.

Ngoài ra, một chút nhanh chóng của google tiết lộ một vài ví dụ cụ thể hơn về những gì đi đâu.

Mô hình: yêu cầu xác thực, mối quan hệ dữ liệu, tạo phương thức, cập nhật phương thức, hủy phương thức, tìm phương thức (lưu ý rằng bạn không chỉ có các phiên bản chung của các phương thức này, mà nếu có một số thứ bạn đang làm, như tìm người có màu đỏ tóc theo tên cuối cùng, sau đó bạn nên trích xuất logic đó để tất cả những gì bạn phải làm là gọi hàm find_redH_by_name ("smith") hoặc đại loại như thế)

Xem: Đây phải là tất cả về định dạng dữ liệu, không phải là xử lý dữ liệu.

Bộ điều khiển: Đây là nơi xử lý dữ liệu. Từ internet: "Mục đích của bộ điều khiển là đáp ứng hành động mà người dùng yêu cầu, lấy bất kỳ tham số nào mà người dùng đã đặt, xử lý dữ liệu, tương tác với mô hình và sau đó chuyển dữ liệu được yêu cầu, ở dạng cuối cùng, tắt cho lượt xem."

Mong rằng sẽ giúp.


0

Nói một cách đơn giản, nói chung, Mô hình sẽ có tất cả các mã liên quan đến (các) bảng, các mối quan hệ đơn giản hoặc phức tạp của chúng (nghĩ chúng là các truy vấn sql liên quan đến nhiều bảng), thao tác dữ liệu / biến để đi đến kết quả bằng logic nghiệp vụ .

Bộ điều khiển sẽ có mã / con trỏ hướng tới các mô hình liên quan cho công việc được yêu cầu.

Lượt xem sẽ chấp nhận đầu vào / tương tác của người dùng và hiển thị phản hồi kết quả.

Bất kỳ sai lệch lớn nào từ những điều này sẽ gây căng thẳng không mong muốn cho phần đó và hiệu suất ứng dụng tổng thể có thể bị ảnh hưởng.


-1

Kiểm tra, thử nghiệm ... Đặt càng nhiều logic càng tốt trong mô hình và sau đó bạn sẽ có thể kiểm tra nó đúng cách. Kiểm thử đơn vị kiểm tra dữ liệu và cách thức hình thành bằng cách kiểm tra mô hình và kiểm tra chức năng kiểm tra cách thức định tuyến hoặc kiểm soát bằng cách kiểm tra các bộ điều khiển, do đó, bạn có thể kiểm tra tính toàn vẹn của dữ liệu trừ khi có ngươi mâu.

j

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.