美文网首页
3. REST, Resources, and Rails -

3. REST, Resources, and Rails -

作者: 介可能是只乌龟 | 来源:发表于2016-04-11 09:39 被阅读0次

    3.12 The RESTful Rails Action Set

    3.12.1 Index

    Typically, an index action provides a representation of a plural (or collection) resource. However, to be clear,not all resource collections are mapped to the index action. Your default index representations will usually be generic, although admittedly that has a lot to do with your application-specific needs. But in general, the index action shows the world the most neutral representation possible.

    class AuctionsController < ApplicationController
      def index
        @auctions = Auction.all
      end
    end
    

    The associated view template will display information about each auction, with links to specific information about each one, and to profiles of the sellers.

    You’ll certainly encounter situations where you want to display a representation of a collection in a restricted way. In our recurring example, users should be able to see a listing of all their bids, but maybe you don’t want users seeing other people’s bids.

    There are a couple of ways to do this. One way is to test for the presence of a logged-in user and decide what to show based on that. But that’s not going to work here. For one thing, the logged-in user might want to see the more public view. For another, the more dependence on server-side state we can eliminate or consolidate, the better.
    So let’s try looking at the two bid lists, not as public and private versions of the same resource, but as different index resources. The difference can be reflected in the routing like:

    resources :auctions do 
      resources :bids do
        get :manage, :on => :collection 
      end
    end
    
    resources:bids
    

    We can now organize the bids controller in such a way that access is nicely layered, using action callbacks
    only where necessary and eliminating conditional branching in the actions themselves:

    class BidsController < ApplicationController 
      before_action :check_authorization, only: :manage
      def index
        @bids = Bid.all
      end
    
      def manage
        @bids = auction.bids
      end
    
      protected
    
      def auction
        @auction ||= Auction.find(params[:auction_id])
      end
    
      def check_authorization 
        auction.authorized?(current_user)
      end 
    end
    

    There’s now a clear distinction between /bids and /auctions/1/bids/manage and the role that they play in your application.

    On the named route side, we’ve now got bids_url and manage_auction_bids_url. We’ve thus preserved the public, stateless face of the /bids resource, and quarantined as much stateful behavior as possible into a discrete member resource, /auctions/1/bids/manage. Don’t fret if this mentality doesn’t come to you naturally. It’s part of the REST learning curve.

    3.12.2 Show

    The RESTful show action is the singular flavor of a resource. That generally translates to a representation ofinformation about one object, one member of a collection.

    class AuctionController < ApplicationController
      def show
        @auction = Auction.find(params[:id])
      end
    end
    

    3.12.3 Destroy

    Destroy actions are good candidates for administrative safeguarding, though of course it depends on whatyou’re destroying. You might want something like this to protect the destroy action.

    class ProductsController < ApplicationController
      before_action :admin_required, only: :destroy
    
    def destroy
      product.destroy
      redirect_to products_url, notice: "Product deleted!"
    end
    

    This approach might be reflected in a simple administrative interface like

    %h1 Products 
    - products.each do |product|
      %p= link_to product.name, product 
      - if current_user.admin?
        %p= link_to "delete", product, method: :delete
    

    The Rails UJS (Unobtrusive JavaScript) API greatly simplifies the HTML emitted for a destroy action, using CSS selectors to bind JavaScript to (in this case) the “delete” link.

    DELETE submissions are dangerous. Rails wants to make them as hard as possible to trigger accidentally—for instance, by a crawler or bot sending requests to your site. So when you specify the DELETE method, JavaScript that submits a form is bound to your “delete” link, along with a rel="nofollow" attribute on the link. Since bots don’t submit forms (and shouldn’t follow links marked “nofollow”), this gives a layer of protection to your code.

    3.12.4 New and Create

    As you’ve already seen, the new and create actions go together in RESTful Rails. A “new resource” is really just an entity waiting to be created. Accordingly, the new action customarily presents a form, and create creates a new record, based on the form input.

    Let’s say you want a user to be able to create (that is, start) an auction. You’re going to need

    1. A new action, which will display a form
    2. A create action, which will create a new Auction object based on the form input, and proceed to a
      view (show action) of that auction.
    protected
    
    def auction
      @auction ||= current_user.auctions.build(params[:auction])
    end
    helper_method:auction
    

    Once the information is filled out by a user, it’s time for the main event: the create action. Unlike new, this action has something to do.

    def create
      if auction.save
        redirect_to auction_url(auction), notice: "Auction created!" 
      else
        render :new 
      end
    end
    

    3.12.5 Edit and Update

    Like new and create, the edit and update actions go together: edit provides a form, and update processes the form input.

    The form for editing a record appears similar to the form for creating one. (In fact, you can put much of it in a partial template and use it for both; that’s left as an exercise for the reader.)

    The form_for method is smart enough to check whether the object you pass to it has been persisted or not. If it has, then it recognizes that you are doing an edit and specifies a PATCH method on the form.

    相关文章

      网友评论

          本文标题:3. REST, Resources, and Rails -

          本文链接:https://www.haomeiwen.com/subject/wwqilttx.html