2017-07-25 44 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