2017-07-25 45 views
1

我正在使用JQuery Datatables gem,并且我已经成功地将它用于我的一个控制器。 SteamGamesRails Datatables,两个控制器中的类似表

SteamGames控制器

def index 
    @steam_games = SteamGame.all 
    respond_to do |format| 
    format.html 
    format.json { render json: SteamGamesDatatable.new(view_context) } 
    end 
end 

数据表本身是非常简单的,从我从git的了。

class SteamGamesDatatable 
    delegate :params, :link_to, :number_to_currency, to: :@view 

    def initialize(view) 
    @view = view 
    end 

    def as_json(options = {}) 
    { 
     sEcho: params[:sEcho].to_i, 
     iTotalRecords: SteamGame.count, 
     iTotalDisplayRecords: games.total_entries, 
     aaData: data 
    } 
    end 

private 

    def data 
    games.map do |game| 
     [ 
     link_to(game.game_name, game), 
     "<img src='#{game.img_icon_url}'/>", 
     game.created_at.strftime("%B %e, %Y"), 
     game.updated_at.strftime("%B %e, %Y"), 
     ] 
    end 
    end 

    def games 
    @games ||= fetch_games 
    end 

    def fetch_games 
    games = SteamGame.order("#{sort_column} #{sort_direction}") 
    games = games.page(page).per_page(per_page) 
    if params[:sSearch].present? 
     games = games.where("game_name like :search", search: "%#{params[:sSearch]}%") 
    end 
    games 
    end 

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

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

    def sort_column 
    columns = %w[game_name img_icon_url created_at] 
    columns[params[:iSortCol_0].to_i] 
    end 

    def sort_direction 
    params[:sSortDir_0] == "desc" ? "desc" : "asc" 
    end 
end 

现在,我将其设置为另一个控制器Collections,但我知道我是非常多余的,但我不知道如何解决它。

“Collections”是用户和SteamGames之间的中间件链接。

所以我想也许我可以只复制整个数据表的代码,并与Collection.steam_game取代SteamGame我将在Rails的控制台,但它告诉我

NoMethodError (undefined method 'steam_game' for #<Class:0x00000007159670>):

这样做的目的是,如果我走到/collection/:id我只会看到集合拥有的游戏。 /steamgames向我显示数据库中的每一场比赛。

如何在新控制器中轻松利用以前的逻辑?

如果我不能,那么我该如何正确引用控制器中的关系链接?

FYI这是我试图使托收出于好奇DataTable中

class CollectionsDatatable 
    delegate :params, :link_to, :number_to_currency, to: :@view 

    def initialize(view) 
    @view = view 
    end 

    def as_json(options = {}) 
    { 
     sEcho: params[:sEcho].to_i, 
     iTotalRecords: Collection.count, 
     iTotalDisplayRecords: games.total_entries, 
     aaData: data 
    } 
    end 

private 

    def data 
    games.map do |game| 
     [ 
     link_to(game.game_name, game), 
     "<img src='#{game.img_icon_url}'/>", 
     game.created_at.strftime("%B %e, %Y"), 
     game.updated_at.strftime("%B %e, %Y"), 
     ] 
    end 
    end 

    def games 
    @games ||= fetch_games 
    end 

    def fetch_games 
    games = Collection.steam_game.order("#{sort_column} #{sort_direction}") ##<--- This is where the error comes from 
    games = games.page(page).per_page(per_page) 
    if params[:sSearch].present? 
     games = games.where("game_name like :search", search: "%#{params[:sSearch]}%") 
    end 
    games 
    end 

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

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

    def sort_column 
    columns = %w[game_name img_icon_url created_at] 
    columns[params[:iSortCol_0].to_i] 
    end 

    def sort_direction 
    params[:sSortDir_0] == "desc" ? "desc" : "asc" 
    end 
end 

我想也许内SteamGamesController附加功能就足够了,所以我可以在写的def fetch_games功能,但我不知道完全理解SteamGamesDatatable.new(view_context)在控制器内调用什么。我〜假设〜初始化(查看)功能?

集模型

class Collection < ApplicationRecord 
    belongs_to :user 
    belongs_to :steam_game 
end 

SteamGames其实很相似

架构的集合/ SteamGames

create_table "collections", force: :cascade do |t| 
    t.string "platform" 
    t.string "name" 
    t.bigint "user_id" 
    t.bigint "steam_game_id" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
    t.index ["steam_game_id"], name: "index_collections_on_steam_game_id" 
    t.index ["user_id"], name: "index_collections_on_user_id" 
    end 

    create_table "steam_games", force: :cascade do |t| 
    t.integer "appid", null: false 
    t.string "game_name", default: "", null: false 
    t.string "img_icon_url", default: "assets/32x32-no.png" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
    end 

更新2 - 传递额外的初始化

class CollectionsDatatable 
    delegate :params, :link_to, :number_to_currency, to: :@view 

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

    def as_json(options = {}) 
    { 
     sEcho: params[:sEcho].to_i, 
     iTotalRecords: @steam_games_resource.count, 
     iTotalDisplayRecords: games.total_entries, 
     aaData: data 
    } 
    end 

private 

    def data 
    games.map do |game| 
     [ 
     link_to(game.game_name, game), 
     "<img src='#{game.img_icon_url}'/>", 
     game.created_at.strftime("%B %e, %Y"), 
     game.updated_at.strftime("%B %e, %Y"), 
     ] 
    end 
    end 

    def games 
    @games ||= fetch_games 
    end 

    def fetch_games 
    games = @steam_games_resource.order("#{sort_column} #{sort_direction}") 
    games = games.page(page).per_page(per_page) 
    if params[:sSearch].present? 
     games = games.where("game_name like :search", search: "%#{params[:sSearch]}%") 
    end 
    games 
    end 

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

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

    def sort_column 
    columns = %w[game_name img_icon_url created_at] 
    columns[params[:iSortCol_0].to_i] 
    end 

    def sort_direction 
    params[:sSortDir_0] == "desc" ? "desc" : "asc" 
    end 
end 

控制器

def show 
    @collection = Collection.find(params[:id]) 
    respond_to do |format| 
     format.html 
     format.json { render json: CollectionsDatatable.new(view_context, @collection.steam_game) } 
    end 
    end 

我已经修改了初始化接受一个新的参数,我可能会变得复杂。我也通过数据表删除了Collection.steam_game的实例。

目前我得到一个 undefined method count'for#`响应,这让我相信它正在试图计数一个单独的游戏。我认为这是因为每个记录都被插入到收集表中 - 所以即使它输出'steam_game',也没有计数。

得到这些后,我认为我的模型可能没有正确设置。

会员应该拥有“收藏” - 收藏品有platformname。该集合应该有游戏。理论上这是正确的,但我注意到每个游戏都在创建一个新的Collections行。

如果我不是有一个 用户 收集 GameCollections 游戏

系统,其中GameCollection不过是“联盟”?和用户有收藏?

最后更新

感谢@下面薯芋的答案,它帮助指导我的妥善解决。

我去了一个4步同步。 用户 - >收藏< - >游戏集合< - Steam_Games

这让我找到谁拥有X steam_game的所有用户,并找到有X steam_game

固定逻辑毕竟收藏,我能使用与提供的建议相同的Datatable。

CollectionsController

def show 
    @collection = Collection.find(params[:id]) 
    respond_to do |format| 
     format.html 
     format.json { render json: SteamGamesDatatable.new(view_context, @collection.steam_games) } 
    end 
    end 

现在,这显示只适用于这个特定集合游戏。我现在需要重新访问命名约定,但这正是我所需要的。

(侧面说明,它也创造了一个确切的重复CollectionsDatatable工作但觉得很重复)

+0

Interresting问题。你可以添加表格和模型的模式吗? – Jeremie

+0

向我们展示了'Collection.rb'模型 – Pavan

回答

1

我不完全了解SteamGamesDatatable.new(view_context)在控制器中调用。我〜假设〜初始化(查看)功能?

你是对的,#new叫做SteamGamesDatatable的#initialize方法。只要您不覆盖@view分配,您可以将任何逻辑添加到您的#initialize

我认为这里值得注意的一个问题是,您正在尝试拨打Collection.steam_game - 您收到NoMethodError,因为Collection类真的不知道在哪里查找此方法。我想你要找的是collection.steam_games。这有两个部分 - 首先,您需要一个Collection的实例来表示具体记录,而现在您提供了一般表示该表的类。其次,我怀疑你的Collection模型中有has_and_belongs_to_many :steam_games,所以你的模型没有单一形式(steam_game)可以查找。

至于你的问题的实质 - 如何重新使用您的代码,这里就是我会做:我只留下类SteamGamesDatatable并在其实例化将增加另一种说法:

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

games_resource你的蒸汽游戏控制器#INDEX行动将所有的Steam游戏(SteamGame.all),并为您的采集控制器这将是具体的集合(如@collection.steam_games)的蒸汽游戏。然后,在你fetch_games你使用games_resource代替混凝土模型来获取游戏。

如果您遵循此路径,并发现自己处于需要为您的集合部署单独的数据表逻辑的情况,则可以始终将所有重复的代码移动到某个模块,并将该模块包含在任意数量的类中我想分享这个逻辑。

希望这有助于你。

更新

如果我不是有一个用户采集GameCollections游戏

系统,其中GameCollection不过是 '联盟'?并且用户 有Collections?

是的,抱歉,我刚刚猜到了您的数据库表结构,这可能导致了一些冗余操作。

但从本质上讲,是的,如果你的收藏belongs_to的一个steam_game,你将不能够输出一个集合的“所有” Steam游戏,因为每一个集合一场比赛。所以你的方法是正确的 - 只需在集合和蒸汽游戏之间创建一个连接表。

所以最终你将有这些关系:

  • 用户has_many :collections
  • GameCollection belongs_to :collection; belongs_to :steam_game
  • 收集belongs_to :user; has_many :game_collections; has_many :steam_games, through: :game_collections
  • SteamGame has_many :game_collections; has_many :collections, through: :game_collections

收集和SteamGame之间的关系会看起来有点ne。与has_and_belongs_to_many,但这是由风格指南皱眉。

+0

感谢您的详细信息 - 你帮我理解并得到进一步的,但我仍然有一个不同的问题,而导致这一小幅题外话。我已经更新了这个问题。 – DNorthrup

+0

@DNorthrup,我已经更新了答案,你在正确的轨道上。 –

+0

非常感谢您的额外细节。我在阅读你的回复并写下来回顾后才意识到这一点,我意识到我应该有一个“独立”模型。我已经改变了数据,一旦我完成了工作,我会看看我是否能够成功实施并更新。 – DNorthrup