मैं उपयोग कर रहा हूँ मेरे नियंत्रक। 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 के लिए सेट कर रहा हूं, लेकिन मुझे एहसास है कि मैं बेहद बेमानी हूं, लेकिन मुझे नहीं पता कि इसे कैसे हल किया जाए।

"संग्रह" उपयोगकर्ता और स्टीमगेम के बीच मिडलवेयर लिंक है।

इसलिए मैंने सोचा कि शायद मैं संपूर्ण डेटाटेबल्स कोड की नकल कर सकता हूं और SteamGame को Collection.steam_game से बदल सकता हूं जैसा कि मैं रेल कंसोल में करूंगा, लेकिन यह मुझे सूचित करता है

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

इसका उद्देश्य यह है कि यदि मैं /collection/:id पर जाता हूं तो मुझे केवल वही गेम दिखाई देंगे जो संग्रह के स्वामित्व में हैं। /steamgames मुझे मेरे डेटाबेस में हर गेम दिखाता है।

मैं नए नियंत्रक के भीतर पिछले तर्क का आसानी से लाभ कैसे उठा सकता हूं?

यदि मैं नहीं कर सकता, तो मैं नियंत्रक के भीतर एक संबंधपरक लिंक को सही तरीके से कैसे संदर्भित करूं?

एफवाईआई यह वह डेटाटेबल है जिसे मैंने संग्रह के लिए उत्सुकता से बनाने की कोशिश की थी

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

मैं सोच रहा था कि शायद स्टीमगेमकंट्रोलर के भीतर एक अतिरिक्त कार्य पर्याप्त हो सकता है, इसलिए मैं def fetch_games फ़ंक्शन को ओवर-राइट कर सकता हूं लेकिन मुझे पूरी तरह से समझ में नहीं आता कि SteamGamesDatatable.new(view_context) नियंत्रक के भीतर क्या कॉल कर रहा है। मैं ~ मानता हूं ~ प्रारंभ (देखें) फ़ंक्शन?

संग्रह मॉडल

class Collection < ApplicationRecord
    belongs_to :user
    belongs_to :steam_game
end

स्टीमगेम वास्तव में बहुत समान है

संग्रह/स्टीमगेम के लिए स्कीमा

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#` प्रतिक्रिया के लिए गिनें', जो मुझे विश्वास दिलाता है कि यह एक विलक्षण खेल पर .गिनने की कोशिश कर रहा है। मुझे लगता है कि ऐसा इसलिए है क्योंकि प्रत्येक रिकॉर्ड संग्रह तालिका में डाला जाता है - इसलिए भले ही यह 'steam_game' आउटपुट करता है, लेकिन कोई गिनती नहीं है।

इतनी दूर जाने के बाद, मुझे लगता है कि मेरे मॉडल ठीक से स्थापित नहीं हो सकते हैं।

एक सदस्य के पास "संग्रह" होना चाहिए - संग्रह में एक platform और एक name होता है। संग्रह में खेल होना चाहिए। सिद्धांत रूप में यह उचित है, लेकिन मैं देख रहा हूँ कि हर खेल एक नई संग्रह पंक्ति बना रहा है।

क्या मुझे इसके बजाय उपयोगकर्ता संग्रह गेमकोलेक्शन गेम होना चाहिए?

सिस्टम जहां गेमकोलेक्शन 'संघ' के अलावा कुछ नहीं है? और उपयोगकर्ता के पास संग्रह हैं?

अंतिम अपडेट

@ यारो के उत्तर के लिए धन्यवाद, इसने मुझे उचित समाधान पर मार्गदर्शन करने में मदद की।

मैं 4 स्टेप सिंक के साथ गया था। उपयोगकर्ता -> संग्रह <-> खेल संग्रह <- Steam_Games

यह मुझे उन सभी उपयोगकर्ताओं को खोजने की अनुमति देता है जिनके पास X steam_game है और उन सभी संग्रहों को ढूंढते हैं जिनमें X steam_game है

तर्क को ठीक करने के बाद, मैं प्रदान की गई अनुशंसा के साथ उसी डेटाटेबल का उपयोग करने में सक्षम था।

मेरा 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 के साथ भी काम किया, लेकिन यह बहुत दोहराव वाला लगा)

1
DNorthrup 25 जुलाई 2017, 06:37
इंटरेस्टिंग सवाल। क्या आप अपनी टेबल और अपने मॉडल की स्कीमा भी जोड़ सकते हैं?
 – 
Jeremie
25 जुलाई 2017, 07:33
हमें Collection.rb मॉडल दिखाएं
 – 
Pavan
25 जुलाई 2017, 08:02

1 उत्तर

सबसे बढ़िया उत्तर

मैं पूरी तरह से समझ नहीं पा रहा हूं कि स्टीमगेम्सडेटाटेबल.न्यू (view_context) नियंत्रक के भीतर क्या कॉल कर रहा है। मैं ~ मानता हूं ~ प्रारंभ (देखें) फ़ंक्शन?

आप सही कह रहे हैं, #new, SteamGamesDatatable की #initialize विधि को कॉल करता है। जब तक आप @view असाइनमेंट को ओवरराइट नहीं करते हैं, तब तक आप अपने #initialize में कोई भी तर्क जोड़ सकते हैं।

मुझे लगता है कि यहां उल्लेखनीय मुद्दा यह है कि आप Collection.steam_game को कॉल करने का प्रयास कर रहे हैं - आपको NoMethodError मिलता है क्योंकि संग्रह वर्ग वास्तव में नहीं जानता कि इस विधि को कहां देखना है। मुझे लगता है कि आप जो खोज रहे हैं वह collection.steam_games है। इसके दो भाग हैं - पहला, आपको ठोस रिकॉर्ड का प्रतिनिधित्व करने के लिए Collection का एक उदाहरण चाहिए, जबकि अब आप उस वर्ग की आपूर्ति करते हैं जो सामान्य रूप से तालिका का प्रतिनिधित्व करता है। दूसरा, मुझे संदेह है, आपके संग्रह मॉडल में आपके पास has_and_belongs_to_many :steam_games है, इसलिए कोई एकवचन रूप नहीं है (steam_game) आपका मॉडल देखने में सक्षम होगा।

आपके प्रश्न के सार के रूप में - अपने कोड का पुन: उपयोग कैसे करें, मैं यहां क्या करूंगा: मैं केवल कक्षा SteamGamesDatatable छोड़ दूंगा और इसके तत्काल पर एक और तर्क जोड़ूंगा:

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

आपके स्टीम गेम कंट्रोलर #index एक्शन के लिए games_resource सभी स्टीम गेम्स (SteamGame.all) होंगे, और आपके कलेक्शन कंट्रोलर के लिए यह उस कंक्रीट कलेक्शन का स्टीम गेम होगा (जैसे @collection.steam_games) . फिर, अपने fetch_games में आप गेम लाने के लिए कंक्रीट मॉडल के बजाय games_resource का उपयोग करेंगे।

यदि आप इस पथ का अनुसरण करते हैं और अपने आप को ऐसी स्थिति में पाते हैं जहां आपको अपने संग्रह के लिए कुछ अलग डेटाटेबल तर्क की आवश्यकता होती है, तो आप हमेशा सभी कोड को एक मॉड्यूल में स्थानांतरित कर सकते हैं, जो कि डुप्लीकेट है, और उस मॉड्यूल को किसी भी कक्षा में शामिल करें जिसे आप चाहते हैं तर्क साझा करें।

आशा है कि यह आपकी मदद करता है।

अपडेट करें

क्या मुझे इसके बजाय उपयोगकर्ता संग्रह गेमकोलेक्शन गेम होना चाहिए?

सिस्टम जहां गेमकोलेक्शन 'संघ' के अलावा कुछ नहीं है? और उपयोगकर्ता के पास संग्रह हैं?

हां, क्षमा करें, मैंने अभी-अभी आपके डेटाबेस तालिका संरचना का अनुमान लगाया है, जिसके कारण कुछ अनावश्यक कार्रवाइयां हो सकती हैं।

लेकिन अनिवार्य रूप से हाँ, यदि आपका संग्रह एक स्टीम_गेम से संबंधित है, तो आप संग्रह के 'सभी' स्टीम गेम को आउटपुट नहीं कर पाएंगे, क्योंकि प्रति संग्रह एक गेम है। तो आपका दृष्टिकोण सही है - बस संग्रह और स्टीम गेम के बीच एक जॉइन टेबल बनाएं।

तो अंत में आपके ये रिश्ते होंगे:

  • उपयोगकर्ता has_many :collections
  • गेमकलेक्शन belongs_to :collection; belongs_to :steam_game
  • संग्रह <कोड> से संबंधित है: उपयोगकर्ता; has_many: game_collections; has_many :steam_games, के माध्यम से: :game_collections
  • स्टीमगेम <कोड> है_मनी: गेम_कलेक्शन; has_many: संग्रह, के माध्यम से: :game_collections

कलेक्शन और स्टीमगेम के बीच का संबंध has_and_belongs_to_many के साथ थोड़ा अधिक साफ-सुथरा दिखाई देगा, लेकिन स्टाइल गाइड द्वारा इस पर ध्यान नहीं दिया जाता है।

1
Yaro Holodiuk 25 जुलाई 2017, 16:29
विवरण के लिए धन्यवाद - आपने मुझे समझने और आगे बढ़ने में मदद की लेकिन मुझे अभी भी एक अलग समस्या है, जिसके कारण यह विषय से थोड़ा हटकर है। मैंने सवाल अपडेट किया है।
 – 
DNorthrup
25 जुलाई 2017, 15:55
@DNorthrup, मैंने जवाब अपडेट कर दिया है, आप सही रास्ते पर हैं।
 – 
Yaro Holodiuk
25 जुलाई 2017, 16:30
अतिरिक्त विवरण के लिए बहुत बहुत धन्यवाद। आपकी प्रतिक्रिया को पढ़ने और समीक्षा के लिए इसे लिखने के बाद मुझे वास्तव में इसका एहसास हुआ, मुझे एहसास हुआ कि मेरे पास एक 'अलग' मॉडल होना चाहिए। मैंने तब से डेटा बदल दिया है, और एक बार जब मैं काम पूरा कर लूंगा तो मैं देखूंगा कि क्या मैं इसे सफलतापूर्वक लागू कर सकता हूं और अपडेट कर सकता हूं।
 – 
DNorthrup
25 जुलाई 2017, 18:04
बहुत बहुत धन्यवाद @Yaro - आपने मुझे हल करने में मदद की, संयोग से, एक बड़ा मुद्दा जो मुझे निराश कर रहा था। मैं अपना पूरा कोड ऊपर पोस्ट करूंगा, और आपको जवाब दूंगा। मेरे पुराने सेट-अप में मुझे 'संग्रह' की हर पंक्ति में नाम + प्लेटफॉर्म जमा करने के लिए मजबूर होना पड़ा जो मुझे बिल्कुल पसंद नहीं आया।
 – 
DNorthrup
25 जुलाई 2017, 19:31
खुशी है कि आपने इसे हल कर लिया है, और उत्तर स्वीकार करने के लिए धन्यवाद!
 – 
Yaro Holodiuk
26 जुलाई 2017, 13:36