【问题标题】:Rails way for different views of a resource资源的不同视图的Rails方式
【发布时间】:2015-05-24 03:59:45
【问题描述】:

假设我们有两种资源:拍卖和出价,并且拍卖有许多可能被建模为嵌套资源的出价。有两种可能的出价集合:rails 应用程序中所有出价的集合和与特定拍卖相关的出价集合。如果用户想要访问这两个集合,我们将如何在控制器中对此进行建模?

一种可能的解决方案是构建两个指向 BidsController#index 操作的路由(auctions/:auction_id/bids 和 bids/),并根据 params[:auction_id] 的存在进行分支。可以想象,如果出价也属于用户,情况会变得更糟,因此在我们的 BidsController 检查 params[:user_id] 以返回与给定用户关联的出价集合时创建另一个条件。处理这个问题的rails方法是什么?

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    处理嵌套资源的开箱即用的解决方案是在子资源控制器中处理它:

    Sampleapp::Application.routes.draw do
    
      resources :bids
    
      resources :users do
        resources :bids # creates routes to BidsController
      end
    
      resources :auctions do
        resources :bids # creates routes to BidsController
      end
    end
    
    class BidsController < ApplicationController
    
      before_action :set_bids, only: [:index]
      before_action :set_bid, only: [:show, :update, :destroy]
    
      def index
      end
    
      # ... new, create, edit, update, destroy   
    
      def set_bid
        # when finding a singular resources we don't have to give a damn if it is nested
        @bid = Bids.find(params[:id])
      end
    
      def set_bids
        @bids = Bids.includes(:user, :auction)
        if params.has_key?(:user_id)
          @bids.where(user_id: params[:user_id])
        elsif params.has_key?(:auction_id)
          @bids.where(auction_id: params[:auction_id])
        end
        @bids.all
      end
    end
    

    这里的优点是您可以通过很少的代码重复获得完整的 CRUD 功能。

    但是,如果您想拥有不同的视图模板或进行不同的排序等,您可以非常简单地覆盖索引路由。

    Sampleapp::Application.routes.draw do
    
      resources :bids
    
      resources :users do
        member do
          get :bids, to: 'users#bids', :bids_per
        end
        resources :bids, except: [:index]
      end
    
      resources :auctions do
        member do
          get :bids, to: 'auction#bids', as: :bids_per
        end
        resources :bids, except: [:index]
      end
    
    end
    

    另一种解决方案是创建一个AuctionsBidsController 并这样定义路由:

    resources :auctions do
      resources :bids, only: [:index], controller: 'AuctionsBids'
      resources :bids, except: [:index]
    end
    

    【讨论】:

      【解决方案2】:

      您不必在每次想要显示出价列表时都让出价控制器参与进来。例如,如果我正在设置这个场景并希望显示与特定拍卖相关的出价列表,我将在拍卖控制器中处理,而不是在出价控制器中处理,如下所示:

      class AuctionsController < ApplicationController
      ...
      def show
        @auction = Auction.find(params[:id])
        @bids = @auction.bids #assuming the bids belong_to your Auction model
      end
      

      然后,在视图 app/views/auctions/show.html.erb 的某处,您可以使用您在出价索引中使用的相同部分列出出价:

      <ul>
        <%= render partial: 'bids/bid', collection: @bids %>
      </ul>
      

      这只是处理这种情况的一种方法。您可以对您的用户模型或应用程序中的任何其他模型执行相同的操作。关键是您不必每次希望模型出现在视图中时都涉及模型的特定控制器。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多