पटरियों में एसटीआई उपवर्गों के लिए मार्गों को संभालने के लिए सर्वोत्तम अभ्यास


175

मेरे रेल विचारों और नियंत्रकों से अटे पड़े रहे redirect_to, link_toऔर form_forविधि कॉल। कभी कभी link_toऔर redirect_toरास्तों वे लिंक कर रहे हैं (उदाहरण के लिए में स्पष्ट कर रहे हैं link_to 'New Person', new_person_path), लेकिन कई बार रास्तों निहित हैं (उदाहरण के लिए link_to 'Show', person)।

मैं अपने मॉडल (कहना Employee < Person) में कुछ एकल तालिका वंशानुक्रम (एसटीआई) जोड़ता हूं , और ये सभी विधियाँ उपवर्ग (उदाहरण) के उदाहरण के लिए टूट जाती हैं Employee; जब रेल निष्पादित होती है link_to @person, तो इसमें त्रुटि होती है undefined method employee_path' for #<#<Class:0x000001022bcd40>:0x0000010226d038>। रेल वस्तु के वर्ग नाम से परिभाषित मार्ग की तलाश में है, जो कर्मचारी है। इन कर्मचारी मार्गों को परिभाषित नहीं किया गया है, और कोई भी कर्मचारी नियंत्रक नहीं है, इसलिए क्रियाएँ भी परिभाषित नहीं हैं।

यह प्रश्न पहले पूछा गया है:

  1. पर StackOverflow , जवाब अपने पूरे codebase में LINK_TO आदि के प्रत्येक उदाहरण संपादित करें, और स्पष्ट रूप से पथ राज्य के लिए है
  2. StackOverflow पर , दो लोग routes.rbमूल वर्ग ( map.resources :employees, :controller => 'people') के लिए उपवर्ग संसाधनों का उपयोग करने का सुझाव देते हैं । उसी SO प्रश्न में शीर्ष उत्तर से पता चलता है कि कोडबेस में प्रत्येक इंस्टेंस ऑब्जेक्ट टाइप-कास्टिंग का उपयोग कर रहा है.becomes
  3. स्टैकऑवरफ्लो में एक और एक , टॉप रिप्लाई अपने आप को कैंप में करने का तरीका है, और हर उपवर्ग के लिए डुप्लिकेट मचान बनाने का सुझाव देता है।
  4. यहाँ एसओ पर फिर से वही सवाल है, जहां शीर्ष उत्तर सिर्फ गलत लगता है (रेल जादू बस काम करता है!)
  5. वेब पर कहीं भी, मुझे यह ब्लॉग पोस्ट मिला जहां F2Andy कोड में हर जगह पथ में संपादन की सिफारिश करता है।
  6. लॉजिकल रियलिटी डिज़ाइन में ब्लॉग पोस्ट सिंगल टेबल इनहेरिटेंस और रैस्टफुल रुट्स पर, उपवर्ग के लिए संसाधनों को सुपरक्लास कंट्रोलर को मैप करने की सिफारिश की गई है, जैसा कि एसओ उत्तर संख्या 2 में है।
  7. एलेक्स रीजनर के पास रेल्स में एक पोस्ट सिंगल टेबल इनहेरिटेंस है , जिसमें वह चाइल्ड क्लासेस के संसाधनों को पेरेंट क्लास में मैप करने की वकालत करता है routes.rb, क्योंकि वह केवल राउटिंग ब्रेक्जिट पकड़ता है link_toऔर redirect_toउससे नहीं form_for। इसलिए वह उपवर्गों को अपनी कक्षा के बारे में झूठ बोलने के लिए मूल वर्ग में एक विधि जोड़ने की सलाह देता है। अच्छा लगता है, लेकिन उनकी पद्धति ने मुझे त्रुटि दी undefined local variable or method `child' for #

जवाब यह है कि सबसे सुंदर लगती है और सबसे आम सहमति है (लेकिन यह सब कुछ नहीं है तो यह है कि सुंदर, और न ही है कि बहुत आम सहमति), अपने लिए संसाधनों को जोड़ने है routes.rb। इसके अलावा यह काम नहीं करता है form_for। मुझे कुछ स्पष्टता चाहिए! उपरोक्त विकल्पों को डिस्टिल करने के लिए, मेरे विकल्प हैं

  1. routes.rbसुपरक्लास के नियंत्रक में उपवर्ग के संसाधनों को मैप करें (और मुझे किसी उपवर्ग पर form_for कॉल करने की आवश्यकता नहीं है)
  2. कक्षाओं को एक-दूसरे से झूठ बनाने के लिए ओवरराइड आंतरिक तरीकों को पार करता है
  3. प्रत्येक उदाहरण को उस कोड में संपादित करें जहां किसी वस्तु की कार्रवाई के लिए पथ को स्पष्ट रूप से या स्पष्ट रूप से लागू किया जाता है, या तो पथ को बदलकर या ऑब्जेक्ट को टाइप-कास्टिंग किया जाता है।

इन सभी परस्पर विरोधी जवाबों के साथ, मुझे एक सत्तारूढ़ की आवश्यकता है। यह मुझे ऐसा लगता है जैसे कोई अच्छा जवाब नहीं है। क्या यह रेल के डिजाइन में विफल है? यदि हां, तो क्या यह एक बग है जो ठीक हो सकता है? या यदि नहीं, तो मुझे उम्मीद है कि कोई मुझे इस पर सीधे सेट कर सकता है, मुझे प्रत्येक विकल्प के पेशेवरों और विपक्षों के माध्यम से चलें (या समझाएं कि यह विकल्प क्यों नहीं है), और कौन सा सही उत्तर है, और क्यों। या क्या कोई सही उत्तर है जो मुझे वेब पर नहीं मिल रहा है?


1
एलेक्स रीजनर के कोड में एक टाइपो था, जिसे मैंने अपने ब्लॉग पर टिप्पणी करने के बाद तय किया था। तो उम्मीद है कि अब एलेक्स का समाधान व्यवहार्य है। मेरा सवाल अभी भी खड़ा है: कौन सा सही समाधान है?
शून्य काल

1
हालाँकि यह लगभग तीन साल पुराना है, मैंने इस ब्लॉग पोस्ट को rookieonrails.blogspot.com/2008/01/… और रेल मेलिंग सूची से जुड़ी बातचीत को जानकारीपूर्ण पाया। उत्तरदाताओं में से एक बहुरूपी सहायकों और नामित सहायकों के बीच अंतर का वर्णन करता है।
ziggurism

2
एक विकल्प जिसे आप सूचीबद्ध नहीं करते हैं, वह है रेल्स को पैच करना ताकि लिंक_ऑटो, फॉर्म_ फॉर और इसी तरह की जगह सिंगल टेबल इनहेरिटेंस के साथ अच्छी हो। यह एक कठिन काम हो सकता है, लेकिन यह कुछ ऐसा है जिसे मैं निश्चित देखना पसंद करूंगा।
एम। स्कॉट फोर्ड

जवाबों:


140

यह सबसे सरल समाधान है जो मैं न्यूनतम दुष्प्रभाव के साथ आने में सक्षम था।

class Person < Contact
  def self.model_name
    Contact.model_name
  end
end

अब url_for @personउम्मीद के मुताबिक नक्शा बनेगा contact_path

यह कैसे काम करता है: URL हेल्पर्स YourModel.model_nameमॉडल पर प्रतिबिंबित करने और कई चीजों के बीच (एकवचन) बहुवचन मार्ग कुंजियों को उत्पन्न करने के लिए भरोसा करते हैं । यहाँ Personमूल रूप से कह रहा हूँContact कि मैं सिर्फ दोस्त की तरह हूँ , उससे पूछो


4
मैं एक ही काम करने के बारे में सोच रहा था, लेकिन चिंतित था कि #model_name रेल में कहीं और इस्तेमाल किया जा सकता है, और यह परिवर्तन सामान्य कामकाज में हस्तक्षेप कर सकता है। कोई विचार?
नाकासिस

3
मैं रहस्यमय अजनबी @nkassis से पूरी तरह सहमत हूं। यह एक शांत हैक है, लेकिन आप कैसे जानते हैं कि आप रेल के इंटर्नल का पर्दाफाश नहीं कर रहे हैं।
tsherif

6
ऐनक। इसके अलावा, हम उत्पादन में इस कोड का उपयोग करते हैं, और मैं यह पुष्टि कर सकता हूं कि यह गड़बड़ नहीं करता है: 1) अंतर-मॉडल संबंध, 2) एसटीआई मॉडल तात्कालिकता ( build_x/ के माध्यम से create_x)। दूसरी ओर, जादू के साथ खेलने की कीमत आप कभी भी 100% निश्चित नहीं हैं कि क्या बदल सकता है।
प्रथम थानार्ट

10
यह i18n को तोड़ता है यदि आप वर्ग के आधार पर विशेषताओं के लिए अलग-अलग मानव नाम रखने की कोशिश कर रहे हैं।
रूफो सांचेज

4
इस तरह पूरी तरह से ओवरराइड करने के बजाय, आप बस उन बिट्स को ओवरराइड कर सकते हैं जिनकी आपको ज़रूरत है। देखें gist.github.com/sj26/5843855
sj26

47

मुझे भी यही समस्या थी। STI का उपयोग करने के बाद, form_forविधि गलत चाइल्ड url पर पोस्ट हो रही थी।

NoMethodError (undefined method `building_url' for

मैंने बाल कक्षाओं के लिए अतिरिक्त मार्गों को जोड़ना और उन्हें उसी नियंत्रकों की ओर इशारा किया

 resources :structures
 resources :buildings, :controller => 'structures'
 resources :bridges, :controller => 'structures'

इसके अतिरिक्त:

<% form_for(@structure, :as => :structure) do |f| %>

इस मामले में संरचना वास्तव में एक इमारत (बाल वर्ग) है

यह मेरे साथ एक काम करने के बाद लगता है form_for


2
यह काम करता है, लेकिन हमारे मार्गों में बहुत सारे अस्वाभाविक रास्ते जोड़ता है। क्या कम घुसपैठ वाले तरीके से ऐसा करने का कोई तरीका नहीं है?
एंडर्स किंडबर्ग

1
आप अपने मार्गों में प्रोग्राम रूट तरीके से सेटअप कर सकते हैं। आरआरबी फ़ाइल, ताकि आप बाल मार्गों को सेटअप करने के लिए थोड़ी मेटा प्रोग्रामिंग कर सकें। हालाँकि, ऐसे वातावरण में जहाँ कक्षाएं कैश नहीं की जाती हैं (उदाहरण के लिए विकास) आपको पहले कक्षाओं को प्री-लोड करना होगा। तो एक रास्ता या दूसरा आपको उपवर्गों को कहीं निर्दिष्ट करने की आवश्यकता है। उदाहरण के लिए gist.github.com/1713398 देखें ।
क्रिस ब्लूम

मेरे मामले में, उपयोगकर्ता के लिए ऑब्जेक्ट नाम (पथ) को उजागर करना वांछनीय नहीं है (और उपयोगकर्ता के लिए भ्रमित)।
laffuste

33

मेरा सुझाव है कि आप इस पर एक नज़र डालें: https://stackoverflow.com/a/605172/445908 , इस पद्धति का उपयोग करके आप "form_for" का उपयोग कर सकेंगे।

ActiveRecord::Base#becomes

2
मुझे इसके लिए स्पष्ट रूप से url सेट करना पड़ा था ताकि दोनों इसे से प्रस्तुत कर सकें और ठीक से सहेज सकें। <%= form_for @child, :as => :child, url: @child.becomes(Parent)
लूलालाल

4
@ लालालाला कोशिश<%= form_for @child.becomes(Parent)
रिचर्ड जोन्स

18

मार्गों में प्रकार का उपयोग करें :

resources :employee, controller: 'person', type: 'Employee' 

http://samurails.com/tutorial/single-table-inheritance-with-rails-4-part-2/


डोमेन बदल गया है, उल्लिखित लेख अब वहां उपलब्ध है: samurails.com/tutorial/…
T_Dnzt

पोस्ट और टिप्पणी में लिंक मर चुके हैं
sasquatch

14

@Pathan थानार्ट के विचार के बाद लेकिन कुछ भी नष्ट नहीं करने की कोशिश कर रहा है। (चूंकि इसमें बहुत जादू शामिल है)

class Person < Contact
  model_name.class_eval do
    def route_key
     "contacts"
    end
    def singular_route_key
      superclass.model_name.singular_route_key
    end
  end
end

अब url_for @person अपेक्षानुसार contact_path पर मैप करेगा।


14

मुझे इस समस्या से भी परेशानी हो रही थी और इस सवाल के जवाब में हमारे समान सवाल आया। इसने मेरे लिए काम किया।

form_for @list.becomes(List)

उत्तर यहां दिखाया गया है: एक ही नियंत्रक के साथ एसटीआई पथ का उपयोग करना

.becomesविधि के रूप में मुख्य रूप से अपने तरह एसटीआई समस्याओं को सुलझाने के लिए इस्तेमाल किया परिभाषित किया गया है form_forएक।

.becomesयहाँ जानकारी: http://apidock.com/rails/ActiveRecord/Base/becomes

सुपर देर से प्रतिक्रिया, लेकिन यह सबसे अच्छा जवाब है जो मुझे मिल सकता है और इसने मेरे लिए अच्छा काम किया। आशा है कि यह कुछ मदद करता है। चीयर्स!


5

ठीक है, इवे को रेल के इस क्षेत्र में एक टन हताशा थी, और निम्नलिखित दृष्टिकोण पर आ गया है, शायद यह दूसरों की मदद करेगा।

सबसे पहले यह जान लें कि नेट पर और उसके आस-पास कई समाधान क्लाइंट द्वारा प्रदान किए गए मापदंडों पर निरंतर उपयोग करने का सुझाव देते हैं। यह एक ज्ञात DoS हमला वेक्टर है क्योंकि रूबी प्रतीकों को इकट्ठा नहीं करता है, इस प्रकार एक हमलावर को मनमाने प्रतीकों को बनाने और उपलब्ध स्मृति का उपभोग करने की अनुमति देता है।

मैंने नीचे दिए गए दृष्टिकोण को लागू किया है जो मॉडल उपवर्गों की तात्कालिकता का समर्थन करता है, और ऊपर दी गई समस्या से सुरक्षित है। यह बहुत कुछ के समान है जो रेल 4 करता है, लेकिन उप-स्तर के एक से अधिक स्तरों (रेल 4 के विपरीत) की अनुमति देता है और रेल 3 में काम करता है।

# initializers/acts_as_castable.rb
module ActsAsCastable
  extend ActiveSupport::Concern

  module ClassMethods

    def new_with_cast(*args, &block)
      if (attrs = args.first).is_a?(Hash)
        if klass = descendant_class_from_attrs(attrs)
          return klass.new(*args, &block)
        end
      end
      new_without_cast(*args, &block)
    end

    def descendant_class_from_attrs(attrs)
      subclass_name = attrs.with_indifferent_access[inheritance_column]
      return nil if subclass_name.blank? || subclass_name == self.name
      unless subclass = descendants.detect { |sub| sub.name == subclass_name }
        raise ActiveRecord::SubclassNotFound.new("Invalid single-table inheritance type: #{subclass_name} is not a subclass of #{name}")
      end
      subclass
    end

    def acts_as_castable
      class << self
        alias_method_chain :new, :cast
      end
    end
  end
end

ActiveRecord::Base.send(:include, ActsAsCastable)

ऊपर दिए गए व्हाट्सएप के समान l डेवेलोपिंग लोडिंग इन डेवेलोपिंग इश्यू ’के लिए कई तरीकों की कोशिश करने के बाद, मैंने केवल वही चीज पाई जो मज़बूती से काम करती थी, वह थी मेरी मॉडल कक्षाओं में _ आवश्यकता_ निर्भरता’ का उपयोग करना। यह सुनिश्चित करता है कि वर्ग लोडिंग विकास में ठीक से काम करता है और उत्पादन में कोई समस्या नहीं पैदा करता है। विकास में, 'आवश्यकता_ निर्भरता' के बिना एआर सभी उपवर्गों के बारे में नहीं जानता है, जो टाइप कॉलम पर मिलान के लिए उत्सर्जित SQL को प्रभावित करता है। इसके अलावा 'आवश्यकता_ निर्भरता' के बिना आप एक ही समय में मॉडल कक्षाओं के कई संस्करणों के साथ एक स्थिति में समाप्त हो सकते हैं! (उदाहरण। यह तब हो सकता है जब आप एक आधार या मध्यवर्ती वर्ग को बदलते हैं, उप-कक्षाएं हमेशा पुनः लोड नहीं लगती हैं और पुरानी कक्षा से उप-वर्गित होती हैं)

# contact.rb
class Contact < ActiveRecord::Base
  acts_as_castable
end

require_dependency 'person'
require_dependency 'organisation'

मैं भी मॉडल_नाम को ओवरराइड नहीं करता हूं जैसा कि ऊपर सुझाव दिया गया है क्योंकि मैं I18n का उपयोग करता हूं और विभिन्न उपवर्गों की विशेषताओं के लिए अलग-अलग तारों की आवश्यकता होती है, उदाहरण के लिए: tax_identifier संगठन के लिए 'ABN', और व्यक्ति के लिए 'TFN' (ऑस्ट्रेलिया में) बन जाता है।

मैं रूट मैपिंग का उपयोग भी करता हूं, जैसा कि ऊपर सुझाव दिया गया है, प्रकार की स्थापना:

resources :person, :controller => 'contacts', :defaults => { 'contact' => { 'type' => Person.sti_name } }
resources :organisation, :controller => 'contacts', :defaults => { 'contact' => { 'type' => Organisation.sti_name } }

रूट मैपिंग के अलावा, मैं InheritedResources और SimpleForm का उपयोग कर रहा हूं और मैं नए कार्यों के लिए निम्नलिखित सामान्य फॉर्म आवरण का उपयोग करता हूं:

simple_form_for resource, as: resource_request_name, url: collection_url,
      html: { class: controller_name, multipart: true }

... और संपादित कार्यों के लिए:

simple_form_for resource, as: resource_request_name, url: resource_url,
      html: { class: controller_name, multipart: true }

और इस काम को करने के लिए, मेरे बेस रिसोर्सकंटोलर में मैं InheritedResource के resource_request_name को देखने के लिए सहायक विधि के रूप में उजागर करता हूं:

helper_method :resource_request_name 

यदि आप InheritedResources का उपयोग नहीं कर रहे हैं, तो अपने 'रिसोर्सकंट्रोलर' में निम्नलिखित की तरह कुछ का उपयोग करें:

# controllers/resource_controller.rb
class ResourceController < ApplicationController

protected
  helper_method :resource
  helper_method :resource_url
  helper_method :collection_url
  helper_method :resource_request_name

  def resource
    @model
  end

  def resource_url
    polymorphic_path(@model)
  end

  def collection_url
    polymorphic_path(Model)
  end

  def resource_request_name
    ActiveModel::Naming.param_key(Model)
  end
end

हमेशा दूसरों के अनुभवों और सुधारों को सुनकर खुश होते हैं।


मेरे अनुभव में (कम से कम रेल 3.0.9 में), निरंतर विफल रहता है यदि स्ट्रिंग द्वारा नामित निरंतर पहले से मौजूद नहीं है। तो मनमाने नए प्रतीकों को बनाने के लिए इसका उपयोग कैसे किया जा सकता है?
लेक्स लिंडसे

4

मैंने हाल ही में रेल 3.0 ऐप में काम करने वाले एक स्थिर एसटीआई पैटर्न को प्राप्त करने के अपने प्रयासों का दस्तावेजीकरण किया । यहाँ TL; DR संस्करण है:

# app/controllers/kase_controller.rb
class KasesController < ApplicationController

  def new
    setup_sti_model
    # ...
  end

  def create
    setup_sti_model
    # ...
  end

private

  def setup_sti_model
    # This lets us set the "type" attribute from forms and querystrings
    model = nil
    if !params[:kase].blank? and !params[:kase][:type].blank?
      model = params[:kase].delete(:type).constantize.to_s
    end
    @kase = Kase.new(params[:kase])
    @kase.type = model
  end
end

# app/models/kase.rb
class Kase < ActiveRecord::Base
  # This solves the `undefined method alpha_kase_path` errors
  def self.inherited(child)
    child.instance_eval do
      def model_name
        Kase.model_name
      end
    end
    super
  end  
end

# app/models/alpha_kase.rb
# Splitting out the subclasses into separate files solves
# the `uninitialize constant AlphaKase` errors
class AlphaKase < Kase; end

# app/models/beta_kase.rb
class BetaKase < Kase; end

# config/initializers/preload_sti_models.rb
if Rails.env.development?
  # This ensures that `Kase.subclasses` is populated correctly
  %w[kase alpha_kase beta_kase].each do |c|
    require_dependency File.join("app","models","#{c}.rb")
  end
end

यह दृष्टिकोण उन समस्याओं के आसपास होता है जिन्हें आप सूचीबद्ध करते हैं और साथ ही कई अन्य मुद्दों को भी जो एसटीआई दृष्टिकोण के साथ हैं।


2

यदि आपके पास कोई नेस्टेड मार्ग नहीं है, तो आप यह कोशिश कर सकते हैं:

resources :employee, path: :person, controller: :person

या आप दूसरे तरीके से जा सकते हैं और कुछ ओओपी-जादू का उपयोग कर सकते हैं जैसे कि यहां वर्णित है: https://coderwall.com/p/yijmuq

दूसरे तरीके से आप अपने सभी नेस्टेड मॉडल के लिए समान सहायक बना सकते हैं।


2

यहां एक सुरक्षित साफ तरीका है जो आपके द्वारा उपयोग किए जाने वाले रूपों और आपके संपूर्ण अनुप्रयोग में काम करता है।

resources :districts
resources :district_counties, controller: 'districts', type: 'County'
resources :district_cities, controller: 'districts', type: 'City'

फिर मैं अपने रूप में। इसके लिए जोड़ा गया टुकड़ा इस प्रकार है: जिला।

= form_for(@district, as: :district, html: { class: "form-horizontal",         role: "form" }) do |f|

उम्मीद है की यह मदद करेगा।


2

मैंने पाया सबसे साफ समाधान निम्न को आधार वर्ग में जोड़ना है:

def self.inherited(subclass)
  super

  def subclass.model_name
    super.tap do |name|
      route_key = base_class.name.underscore
      name.instance_variable_set(:@singular_route_key, route_key)
      name.instance_variable_set(:@route_key, route_key.pluralize)
    end
  end
end

यह सभी उपवर्गों के लिए काम करता है और पूरे मॉडल नाम ऑब्जेक्ट को ओवरराइड करने की तुलना में अधिक सुरक्षित है। केवल रूट कुंजियों को लक्षित करके, हम I18n को तोड़ने के बिना रूटिंग समस्याओं को हल करते हैं या मॉडल द्वारा ओवरराइड करने से होने वाले किसी भी संभावित साइड इफेक्ट को खतरे में डालते हैं जैसा कि रेल द्वारा परिभाषित किया गया है।


1

अगर मैं इस तरह से एक एसटीआई विरासत पर विचार करता हूं:

class AModel < ActiveRecord::Base ; end
class BModel < AModel ; end
class CModel < AModel ; end
class DModel < AModel ; end
class EModel < AModel ; end

'ऐप / मॉडल / a_model.rb' में मैं जोड़ता हूं:

module ManagedAtAModelLevel
  def model_name
    AModel.model_name
  end
end

और फिर एएमडेल वर्ग में:

class AModel < ActiveRecord::Base
  def self.instanciate_STI
    managed_deps = { 
      :b_model => true,
      :c_model => true,
      :d_model => true,
      :e_model => true
    }
    managed_deps.each do |dep, managed|
      require_dependency dep.to_s
      klass = dep.to_s.camelize.constantize
      # Inject behavior to be managed at AModel level for classes I chose
      klass.send(:extend, ManagedAtAModelLevel) if managed
    end
  end

  instanciate_STI
end

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


1

यह तरीका मेरे लिए ठीक है (इस विधि को आधार वर्ग में परिभाषित करें):

def self.inherited(child)
  child.instance_eval do
    alias :original_model_name :model_name
    def model_name
      Task::Base.model_name
    end
  end
  super
end

1

आप विधि बना सकते हैं जो प्यूरपॉज रूट करने के लिए डमी पैरेंट ऑब्जेक्ट देता है

class Person < ActiveRecord::Base      
  def routing_object
    Person.new(id: id)
  end
end

और उसके बाद form_for @ employee.rout_object पर कॉल करें, जो बिना टाइप के व्यक्ति वर्ग ऑब्जेक्ट को लौटा देगा


1

@ Prathan-thananart उत्तर के बाद, और कई एसटीआई वर्गों के लिए, आप मूल मॉडल में निम्न जोड़ सकते हैं ->

class Contact < ActiveRecord::Base
  def self.model_name
    ActiveModel::Name.new(self, nil, 'Contact')
  end
end

यही कारण है कि के रूप में पैरामीटर भेजने के लिए संपर्क डेटा के साथ प्रत्येक प्रपत्र कर देगा params[:contact]के बजाय params[:contact_person], params[:contact_whatever]


-6

हैकिश, लेकिन समाधानों की सूची में सिर्फ एक और।

class Parent < ActiveRecord::Base; end

Class Child < Parent
  def class
    Parent
  end
end

रेल पर काम करता है 2.x और 3.x


5
यह एक समस्या को ठीक करता है, लेकिन दूसरा बनाता है। अब जब आप Child.newइसे करने की कोशिश करते हैं तो यह Parentउपवर्ग के बजाय एक वर्ग देता है । इसका मतलब यह है कि आप उप नियंत्रक को बड़े पैमाने पर असाइनमेंट के माध्यम से एक नियंत्रक के माध्यम से नहीं बना सकते हैं (क्योंकि typeडिफ़ॉल्ट रूप से एक संरक्षित विशेषता है) जब तक आप स्पष्ट रूप से टाइप विशेषता निर्धारित नहीं करते हैं।
क्रिस ब्लूम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.