通过视图模型或视图助手访问视图中的数据库是否打破了MVC范式?

时间:2011-12-29 02:23:30

标签: ruby-on-rails rails-activerecord

我相信以下所有内容都打破了MVC范式,但是想要仔细检查是否是这种情况。在所有情况下,视图都直接访问数据而不是传入数据。根据我对MVC的理解,它永远不应该这样做。控制器应获取渲染视图所需的所有数据,以便不直接耦合视图和模型。我的理解是否正确?

  1. 通过视图助手访问数据库

    # in app/helpers/view_helper.hrb
    def some_view_helper(person_id)
      @person = Person.find(person_id)
    end
    
  2. 通过视图助手访问另一个Web服务器

    # in app/helpers/view_helper.hrb
    def another_view_helper(person_id)
      # makes http request over the wire to get json back
      @json = WebService.get_person(person_id)
    end
    
  3. 通过视图模型访问数据库

    # in apps/controller/person_controller.rb
    def show
      @person = Person.find(params[:id])
      @page_model = PageModel.new(@person)
    end
    
    #in app/views/persons/show.html.erb
    <% @page_model.friends.each do |friend| %>
      ...
    <% end %>
    
    #in app/models/person.rb
    class Person < ActiveRecord::Base
      has_many :friends
    end
    
    #in app/models/page_models/page_model.rb
    def initialize(person)
      @person = person
    end
    
    def friends
      @person.friends
    end
    
  4. 访问Web服务器以通过视图模型获取数据

    # in apps/controller/person_controller.rb
    def show
      @person = Person.find(params[:id])
      @page_model = PageModel.new(@person)
    end
    
    #in app/views/persons/show.html.erb
    <% @page_model.friends.each do |friend| %>
       ...
    <% end %>
    
    #in app/models/page_models/page_model.rb
    def initialize(person)
      @person = person
    end
    
    def friends
      WebService.get_friends_for_person(person_id)
    end
    

1 个答案:

答案 0 :(得分:1)

对于1和2,您只需在控制器中设置实例变量(@person)。

对于3,您的视图代码并不是那么糟糕,但为什么要有单独的页面模型?您还可以在控制器中预先加载好友:

# in apps/controller/person_controller.rb
def show
  @person = Person.find(params[:id], :include => :friends)
  @friends = @person.friends
end

示例4有点糟糕,因为您在视图中进行外部Web服务调用。不要那样做。

本文有一个很好的例子,说明理想的干净视图:http://warpspire.com/posts/mustache-style-erb/