Нужны две кнопки для индексирования всех элементов или элементов, назначенных текущему пользователю?

Ruby 2.0.0, Rails 4.0.3, jquery-datatables-rails 2.2.3 (DataTables 1.10.2)

Мне бы хотелось, чтобы в моей форме было две кнопки: одна для отображения всех элементов, а другая для отображения только тех элементов, которые в данный момент назначены текущему пользователю. Учитывая, что я даже иду по правильному пути для этого, и я не уверен, что у меня есть, у меня есть две проблемы. Или я на неверном пути?

В действии контроллера я пытаюсь передать текущего пользователя представлению, которое создается контроллером ItemsDatatable. Отладка показывает, что действие index выполняется дважды. В первый раз пользователь настроен так, как ожидалось. Во второй раз пользователь имеет значение nil, поэтому он никогда не передается в ItemsDatatable. Почему это и как мне это исправить? (Если я безоговорочно установлю пользователя в действии index контроллера, оно будет пропущено.)

Вторая проблема более эзотерическая. Если я могу установить @user в инициализации, как мне передать это as_json и другим действиям ItemsDatatable? Я предполагаю, что это специфично для jquery-datatables-rails, и мне, возможно, придется выяснить его логику, чтобы решить, как это сделать? Или есть Rails способ сделать это красиво?

К вашему сведению, это шаблон DataTables из RailsCasts 340, который был обновлен для DataTables 1.10.2.

Спасибо за помощь.

Кнопки главной страницы:

  <%= link_to 'Status-My Items',  items_path(select: "mine"), :class => 'btn btn-primary' %>
  <%= link_to 'Status-All Items', items_path(select: "all" ), :class => 'btn btn-primary' %>

Действие элемента ItemsController:

  def index
    user ||= params[:select] == "mine" ? current_user : nil
    respond_to do |format|
      format.html
      format.json { render json: ItemsDatatable.new(view_context, user) }
    end
  end

ItemsDatatable контроллер:

class ItemsDatatable < ApplicationController
  delegate :params, :h, :link_to, :edit_item_path, :new_item_path, :location, to: :@view

  def initialize(view, user)
    @view = view
    @user = user
  end

  def as_json(options = {})
    {
        draw: params[:draw].to_i,
        recordsTotal: Item.count,
        recordsFiltered: items.total_entries,
        data: data
    }
  end

  private

  def data
    todays_date = Date.today
    items.map do |item|
      [
          link_to(item.stock_number, edit_item_path(item))
      ]
    end
  end

  def items
    @items ||= fetch_items
  end

  def fetch_items
    items = Item.order("#{sort_column} #{sort_direction}")
    items = items.page(page).per_page(per_page)
    if params[:search][:value].present?
      items = items.where("stock_number ilike :search, search: "%#{params[:search][:value]}%")
    end
    items
  end

  def page
    params[:start].to_i/per_page + 1
  end

  def per_page
    params[:length].to_i > 0 ? params[:length].to_i : 10
  end

  def sort_column
    columns = %w[stock_number]
    columns[params[:order]['0'][:column].to_i]
  end

  def sort_direction
    params[:order]['0'][:dir] == "desc" ? "desc" : "asc"
  end
end

1 ответ

Решение

Мне кажется, что ответом на оба вопроса является использование хранилища сессии:

Вид:

  <%= link_to 'My Items',  items_path(my_view: current_user.id),
              class: 'btn btn-primary' %>
  <%= link_to 'All Items', items_path(my_view: "all"),
              class: 'btn btn-primary' %>

Контроллер:

session[:my_view] ||= params[:my_view]

Где используется:

unless @view.session[:my_view] == "all"
  user = User.find(@view.session[:my_view]).name
  items = items.where("clshadow = \'#{user}\'")
end
@view.session[:my_view] = nil
Другие вопросы по тегам