Разбиение на Ruby On Rails - ведение параметров сортировки - PullRequest
0 голосов
/ 07 августа 2011

Я уже некоторое время пытаюсь выучить Ruby & RoR, но у меня возникла проблема с поддержанием сортировки по ссылкам на страницы. У меня есть часть архитектуры MVC, так как я использовал подобную архитектуру в приложениях PHP. Я унаследовал приложение от другой группы разработчиков, которое содержит ошибку, которую мне нужно исправить.

На странице, отображающей клиентов для данного пользователя, существует разбиение на страницы для разделения списка на страницы по 20. Каждый столбец можно использовать для сортировки таблицы данных. После сортировки страницы по альтернативному столбцу, щелкнув одну из ссылок на страницы, вы перейдете на эту страницу, но вернете порядок сортировки к порядку по умолчанию.

Итак, общая идея заключается в том, что мне нужно сохранить параметры GET текущей страницы (с указанием порядка сортировки) в ссылках на нумерацию страниц.

Некоторые примеры URL:

Вот кодовые биты, которые, я думаю, могут иметь значение.

Контроллер: контроллеры / customer_controller.rb

def index
  @customer = Customer.new(params[:customer])
  @customer.user_id = (current_user.sales_director? || current_user.admin?) ? params[:user_id] : current_user.id
  @customer_pages, @customers = paginate  :customers,
                                        :joins => "INNER JOIN sources ON customers.source_id=sources.id INNER JOIN locations ON customers.location_id=locations.id",
                                        :select => "customers.*, sources.name AS source_name, locations.name AS location_name",
                                        :conditions => @customer.search_conditions,
                                        :per_page => 20,
                                        :order => @customer.search_order
end

Просмотр: просмотры / клиенты / index.haml

%h1=User.find(params[:user_id]).full_name + "'s Customers"

.action_links
  - if !current_user.viewer?
    = link_to '+ Add New Customer', new_customer_path
    |
  = link_to 'View Follow Up Reminders', reminders_user_path(@user)

=render :partial => 'search_form'
%br/

- if @customer_pages.page_count > 1
  .pagination_links
    Go to page:
    = link_to '<', pagination_prev_link if pagination_prev_link
    = pagination_links @customer_pages, :window_size => 5, :params => flatten_hash(params.dup.delete(:page))
    = link_to '>', pagination_next_link(@customer_pages.page_count) if pagination_next_link(@customer_pages.page_count)


- if @customers.size > 0
  = render :partial => 'search_results'
- else
  %p.no_results No customers matching your search criteria were found. Please try searching again.


- if @customer_pages.page_count > 1
  .pagination_links
    Go to page:
    = link_to '<', pagination_prev_link if pagination_prev_link
    = pagination_links @customer_pages, :window_size => 5, :params => flatten_hash(params.dup.delete(:page))
    = link_to '>', pagination_next_link(@customer_pages.page_count) if pagination_next_link(@customer_pages.page_count)

Я бы очень признателен за любую помощь, которую я мог бы получить, как я мог бы изменить это, чтобы это произошло. Если вам понадобятся другие примеры кода, просто дайте мне знать.

Спасибо!

РЕДАКТИРОВАТЬ: ЗДЕСЬ КОД ДЛЯ ПРЕДЫДУЩИХ И СЛЕДУЮЩИХ СТРАНИЦ ССЫЛКИ (ЭТА РАБОТАЕТ ШТРАФ). НАДЕЖДА, ЭТО ПУТЬ, КОТОРЫЙ МОЖЕТ ПОЛЕЗНО ПОЛУЧИТЬ СПОСОБ ПОЛУЧИТЬ # ССЫЛКИ ДЛЯ РАБОТЫ ХОРОШО.

#module ApplicationHelper

  # Took these next 2 methods from a blog post I found here: http://marklunds.com/articles/one/314
  # to help deal with a nested hash in params
  def flatten_hash(hash = params, ancestor_names = [])
    return if !hash 
    flat_hash = {}
    hash.each do |k, v|
      names = Array.new(ancestor_names)
      names << k
      if v.is_a?(Hash)
        flat_hash.merge!(flatten_hash(v, names))
      else
        key = flat_hash_key(names)
        key += "[]" if v.is_a?(Array)
        flat_hash[key] = v
      end
    end
    flat_hash
  end

  def flat_hash_key(names)
    names = Array.new(names)
    name = names.shift.to_s.dup 
    names.each do |n|
      name << "[#{n}]"
    end
    name
  end


  # pagination link helpers (because default one is kinda broken)
  def pagination_prev_link
    prev_link = params.clone
    if params[:page].to_i - 1 > 0
      prev_link[:page] = prev_link[:page].to_i - 1
      flatten_hash(prev_link)
    else
      false
    end
  end

  def pagination_next_link(max)
    next_link = params.clone
    if params[:page].to_i < max
      next_link[:page] = 1 if next_link[:page].to_i == 0
      next_link[:page] = next_link[:page].to_i + 1
      flatten_hash(next_link)
    else
      false
    end
  end

Ответы [ 2 ]

0 голосов
/ 07 августа 2011

Ладно, так что я достаточно хорошо знал о том, что я делал, чтобы придумать что-то вроде решения проблемы ... но похоже, что оно работает как положено.

Добавлена ​​новая функцияпомощнику приложения:

  def pagination_page_link(p)
    page_link = params.clone
    page_link[:page] = p
    flatten_hash(page_link)
  end

Следующее использовалось в файле представления дважды для замены исходных строк, выводящих пронумерованные ссылки.

- if @customer_pages.page_count > 1
  .pagination_links
    Go to page:
    = link_to '&lt;', pagination_prev_link if pagination_prev_link
    - @customer_pages.each do |page|
      = page.number if @customer_pages.current_page.number == page.number
      = link_to page.number, pagination_page_link(page.number) unless @customer_pages.current_page.number == page.number
    -#= pagination_links @customer_pages, :window_size => 5, :params => flatten_hash(params.dup.delete(:page))
    = link_to '&gt;', pagination_next_link(@customer_pages.page_count) if pagination_next_link(@customer_pages.page_count)
0 голосов
/ 07 августа 2011

Я не уверен, что именно используется для нумерации страниц.Если бы вы могли пойти с чем-то вроде kaminari или will_paginate , они бы позаботились о таких вещах для вас.

Если это слишком много рефакторинга, вот что-то дляпопробуйте выполнить текущую настройку.

Похоже, что :params => flatten_hash(params.dup.delete(:page)) делает то, что вы уже искали.Проблема в том, что это только для ссылок с номерами страниц, а не для предыдущих / следующих ссылок.Работают ли нумерованные ссылки нумерации страниц или они тоже не работают?

На вашем месте я бы попробовал изменить следующую и предыдущую ссылки на что-то вроде этого и посмотреть, работает ли он.

= link_to '&lt;', pagination_prev_link(:params => flatten_hash(params.dup.delete(:page))) if pagination_prev_link
...
= link_to '&gt;', pagination_next_link(@customer_pages.page_count, :params => flatten_hash(params.dup.delete(:page))) if pagination_next_link(@customer_pages.page_count)

Если это не сработает, может быть, вы сможете узнать, где pagination_prev_link и pagination_next_link и определить и опубликовать этот код.

ОБНОВЛЕНИЕ:

Я действительно не понимаю, зачем это нужнодля flatten_hash метод есть.Так что я бы попробовал это без этого.Кроме того, на всякий случай может также быть более точным описание параметров хеширования, даже если это не обязательно.

= pagination_links @customer_pages, {:window_size => 5, :params => params.dup.delete(:page)}, {}

Если это не сработает, попробуйте передать некоторые параметры вручнуюпросто чтобы посмотреть, работает ли он вообще.

= pagination_links @customer_pages, {:params => {:test_param => 1}}, {}
...