解决不同的路线和保持干燥

时间:2014-02-02 14:33:32

标签: ruby-on-rails

想保持我的意见干!

问题描述:

我已经成功实现了AJAX分页,但是我必须在下面的示例中使用静态路径 - 使用root_path来“加载更多产品”链接。用户访问根URL时这很好,但访问/ s / [storename]或/ c / [collectionname]时显然会中断

我无法从概念上理解我需要做些什么来重构这个?如果可能的话,我想保留/ t / s / c路由。

有什么想法吗?

路由

root_path        GET     /               products#tile
tag_view_path        GET     /t/:tag(.:format)       products#tile
store_view_path      GET     /s/:store_slug(.:format)    products#tile
collection_view_path     GET     /c/:collection_slug(.:format)   products#tile

products_controller

def tile

    # /t/:tag           Show all by tag
    # /s/:store_slug        Show all by store
    # /c/:collection_slug       Show all by collection
    # Nothing passed        Show all by rank

    if params[:tag]
        # find by tag
        # to be implemented
    elsif params[:store_slug]
        store = Store.friendly.find(params[:store_slug])
        @products = store.products.paginate(:page => params[:page]).order('rank DESC') 
        respond_to do |format|
            format.html
            format.js 
        end
    elsif params[:collection_slug]
        collection = Collection.friendly.find(params[:collection_slug])
        @products = collection.products.paginate(:page => params[:page]).order('rank DESC') 
        respond_to do |format|
            format.html
            format.js 
        end
    else
        @products = Product.paginate(:page => params[:page]).order('rank DESC') 
        respond_to do |format|
            format.html
            format.js 
        end

    end


end

tile.html.erb(下一页链接)

  <div><%= link_to 'Load More Products', root_path(:page => @products.next_page), :class    => 'load-more-products', :remote => true if @products.next_page %></div>

tile.js.erb(JS附加ajax响应)

 $('.column-holder').append('<%= escape_javascript(render partial: "product", collection: @products) %>');
 $('a.load-more-products').attr('href', '<%= root_path page: @products.next_page %>');

按要求提供路线

  # product short URL /p/slug-name-for-title
  match 'p/:product_slug',          to: 'products#show',      via: 'get', as: 'product_view'

  # show products by tag /t/tagname
  match 't/:tag',                   to: 'products#tile',      via: 'get', as: 'tag_view'

  # show products by store /s/store-slug-name
  match 's/:store_slug',            to: 'products#tile',      via: 'get', as: 'store_view'

  # show products by collection /c/collection-slug-name
  match 'c/:collection_slug',       to: 'products#tile',      via: 'get', as: 'collection_view'

1 个答案:

答案 0 :(得分:1)

您需要将“where”传递给您的视图,以便为正确的事物分页。

我会寻找一种方法来制作这3种或4种不同的方法。 短期内,你可以将它干掉一点。

# NOTE you may need to do something like
# helper ProductHelper # to get the method from the "other file" below
def tile

# /t/:tag           Show all by tag
# /s/:store_slug        Show all by store
# /c/:collection_slug       Show all by collection
# Nothing passed        Show all by rank

    if params[:tag]
        # find by tag
        # to be implemented
    elsif params[:store_slug]
        store = Store.friendly.find(params[:store_slug])
        @products = store.products.paginate(:page => params[:page]).order('rank DESC') 
    elsif params[:collection_slug]
        collection = Collection.friendly.find(params[:collection_slug])
        @products = collection.products.paginate(:page => params[:page]).order('rank DESC') 
    else
        @products = Product.paginate(:page => params[:page]).order('rank DESC') 
    end
    respond_to do |format|
        format.html
        format.js 
    end
end

以上是#products_by_tag,#product_by_store,#product_by_collection和#index for all。这是另一回事。

class ProductHelper
   def url_for_tile_type(options = {})
     if params[:tag]
       tag_view_path(options)
     elsif params[:store_slug]
       store_view_path(options)
     elsif params[:collection_slug]
        collection_view_path(options)
     else
       product_path(options)
     end
   end
end

然后你的js视图变为,

$('.column-holder').append('<%= escape_javascript(render partial: "product", collection: @products) %>');
$('a.load-more-products').attr('href', '<%= url_for_tile_type page: @products.next_page %>');

我们已经实现了一些功能类似于polymorphic_url_for的功能,并将我们发送到了“右侧”的下一页。

我认为,routes.rb match在rails 4中已被弃用。如果您使用的是rails 3+,则可以这样做。

 # product short URL /p/slug-name-for-title
  get 'p/:product_slug',          to: 'products#show',      as: 'product_view'

  # show products by tag /t/tagname
  get 't/:tag',                   to: 'products#tile',      as: 'tag_view'

  # show products by store /s/store-slug-name
  get 's/:store_slug',            to: 'products#tile',      as: 'store_view'

  # show products by collection /c/collection-slug-name
  get 'c/:collection_slug',       to: 'products#tile',      as: 'collection_view'