मैंने ActiveRecord को कैसे आगे बढ़ाया जाए, इसके बारे में कुछ रीडिंग की है: बेस क्लास इसलिए मेरे मॉडल में कुछ विशेष विधियाँ होंगी। इसे बढ़ाने का आसान तरीका क्या है (स्टेप बाय स्टेप ट्यूटोरियल)?
मैंने ActiveRecord को कैसे आगे बढ़ाया जाए, इसके बारे में कुछ रीडिंग की है: बेस क्लास इसलिए मेरे मॉडल में कुछ विशेष विधियाँ होंगी। इसे बढ़ाने का आसान तरीका क्या है (स्टेप बाय स्टेप ट्यूटोरियल)?
जवाबों:
कई दृष्टिकोण हैं:
ActiveSupport :: अधिक जानकारी के लिए चिंता दस्तावेज़ पढ़ें ।
निर्देशिका active_record_extension.rb
में नामक एक फ़ाइल बनाएँ lib
।
require 'active_support/concern'
module ActiveRecordExtension
extend ActiveSupport::Concern
# add your instance methods here
def foo
"foo"
end
# add your static(class) methods here
class_methods do
#E.g: Order.top_ten
def top_ten
limit(10)
end
end
end
# include the extension
ActiveRecord::Base.send(:include, ActiveRecordExtension)
config/initializers
नामक निर्देशिका में एक फ़ाइल बनाएँ और फ़ाइल में extensions.rb
निम्न पंक्ति जोड़ें:
require "active_record_extension"
टोबी के उत्तर का संदर्भ लें ।
config/initializers
निर्देशिका में एक फ़ाइल बनाएँ active_record_monkey_patch.rb
।
class ActiveRecord::Base
#instance method, E.g: Order.new.foo
def foo
"foo"
end
#class method, E.g: Order.top_ten
def self.top_ten
limit(10)
end
end
जॅमी ज़्विन्स्की द्वारा नियमित भावों के बारे में प्रसिद्ध उद्धरण को बंदर-पेटिंग से जुड़ी समस्याओं का वर्णन करने के लिए फिर से प्रस्तुत किया जा सकता है।
कुछ लोग, जब एक समस्या का सामना करते हैं, तो सोचते हैं कि "मुझे पता है, मैं बंदर के पेटिंग का उपयोग करूंगा।" अब उन्हें दो समस्याएं हैं।
बंदर पालना आसान और त्वरित है। लेकिन, बचाए गए समय और प्रयास को हमेशा भविष्य में वापस ले लिया जाता है; चक्रवृद्धि ब्याज के साथ। इन दिनों मैं रेलिंग को सांत्वना देने के लिए रेलिंग कंसोल में घोल को सीमित करता हूं।
require
के अंत में फ़ाइल है environment.rb
। मैंने अपने उत्तर में यह अतिरिक्त कदम जोड़ा है।
ImprovedActiveRecord
और इनहेरिट करना होगा, जब आप उपयोग कर रहे हैं, तो आप module
प्रश्न में कक्षा की परिभाषा को अपडेट कर रहे हैं। मैं वंशानुक्रम (जावा / सी ++ अनुभव के वर्षों का कारण) का उपयोग करता था। इन दिनों मैं ज्यादातर मॉड्यूल का उपयोग करता हूं।
Refinements
जिसमें अधिकांश मामलों को संबोधित किया गया है ( बंदरहट्ज.कॉम डॉट कॉम/11/11/30/ruby-2-0-refinements-in-ults )। कभी-कभी एक सुविधा सिर्फ आपको भाग्य को लुभाने के लिए मजबूर करने के लिए होती है। और कभी-कभी आप करते हैं।
आप केवल कक्षा का विस्तार कर सकते हैं और केवल विरासत का उपयोग कर सकते हैं।
class AbstractModel < ActiveRecord::Base
self.abstract_class = true
end
class Foo < AbstractModel
end
class Bar < AbstractModel
end
abstract_models
। मैं इसे कहां रखूं?
self.abstract_class = true
अपने में जोड़ें AbstractModel
। रेल अब मॉडल को एक सार मॉडल के रूप में पहचानेंगे।
AbstractModel
डेटाबेस की तलाश की। कौन जानता था कि एक साधारण सेटर मुझे DRY चीजों में मदद करेगा! (मैं ऐंठने लगा था ... बुरा लगा था)। धन्यवाद टोबी और हरीश!
आप भी उपयोग कर सकते हैं ActiveSupport::Concern
और अधिक रेल कोर मुहावरेदार हो सकते हैं जैसे:
module MyExtension
extend ActiveSupport::Concern
def foo
end
module ClassMethods
def bar
end
end
end
ActiveRecord::Base.send(:include, MyExtension)
[संपादित करें] @ डैनियल की टिप्पणी के बाद
फिर आपके सभी मॉडल foo
में एक विधि विधि के ClassMethods
रूप में शामिल विधि और वर्ग विधियों के रूप में शामिल तरीके होंगे। जैसे FooBar < ActiveRecord::Base
आपके पास होगा: FooBar.bar
औरFooBar#foo
http://api.rubyonrails.org/classes/ActiveSupport/Concern.html
InstanceMethods
रेल 3.2 से हटा दिया गया है, बस अपने तरीकों को मॉड्यूल बॉडी में डालें।
ActiveRecord::Base.send(:include, MyExtension)
एक इनिशियलाइज़र में रखा और फिर यह मेरे लिए काम किया। रेल्स 4.1.9
रेल 4 के साथ, अपने मॉडल को संशोधित और डीआरवाई करने के लिए चिंताओं का उपयोग करने की अवधारणा पर प्रकाश डाला गया है।
चिंताएं मूल रूप से आपको एक मॉडल के समान कोड या एक मॉडल में कई मॉडलों में समान समूह बनाने की अनुमति देती हैं और फिर मॉडल में इस मॉड्यूल का उपयोग करती हैं। यहाँ एक उदाहरण है:
एक अनुच्छेद मॉडल, एक घटना मॉडल और एक टिप्पणी मॉडल पर विचार करें। एक लेख या ए घटना में कई टिप्पणियां हैं। एक टिप्पणी या तो लेख या घटना की है।
परंपरागत रूप से, मॉडल इस तरह दिख सकते हैं:
टिप्पणी मॉडल:
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
end
लेख मॉडल:
class Article < ActiveRecord::Base
has_many :comments, as: :commentable
def find_first_comment
comments.first(created_at DESC)
end
def self.least_commented
#return the article with least number of comments
end
end
इवेंट मॉडल
class Event < ActiveRecord::Base
has_many :comments, as: :commentable
def find_first_comment
comments.first(created_at DESC)
end
def self.least_commented
#returns the event with least number of comments
end
end
जैसा कि हम देख सकते हैं, इवेंट और आर्टिकल मॉडल दोनों के लिए कोड कॉमन का एक महत्वपूर्ण हिस्सा है। चिंताओं का उपयोग करके हम एक अलग मॉड्यूल में इस सामान्य कोड को निकाल सकते हैं।
इसके लिए एप्लिकेशन / मॉडल / चिंताओं में एक टिप्पणी करने योग्य .rb फ़ाइल बनाएं।
module Commentable
extend ActiveSupport::Concern
included do
has_many :comments, as: :commentable
end
# for the given article/event returns the first comment
def find_first_comment
comments.first(created_at DESC)
end
module ClassMethods
def least_commented
#returns the article/event which has the least number of comments
end
end
end
और अब आपके मॉडल इस तरह दिखते हैं:
टिप्पणी मॉडल:
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
end
लेख मॉडल:
class Article < ActiveRecord::Base
include Commentable
end
इवेंट मॉडल
class Event < ActiveRecord::Base
include Commentable
end
एक बात यह है कि मैं कंसर्न का उपयोग करते समय हाइलाइट करना चाहूंगा कि कंसर्न का इस्तेमाल 'टेक्निकल' ग्रुपिंग के बजाय 'डोमेन आधारित' ग्रुपिंग के लिए किया जाना चाहिए। उदाहरण के लिए, एक डोमेन ग्रुपिंग 'कमेंटेबल', 'टैगेबल' आदि की तरह है। एक तकनीकी आधारित ग्रुपिंग 'फाइंडरमैथोड्स', 'वैलिडेशनमेथोड्स' की तरह होगा।
यहां एक पोस्ट का लिंक दिया गया है जो मुझे मॉडल्स में चिंताओं को समझने के लिए बहुत उपयोगी लगा।
आशा है कि राइटअप मदद करता है :)
चरण 1
module FooExtension
def foo
puts "bar :)"
end
end
ActiveRecord::Base.send :include, FooExtension
चरण 2
# Require the above file in an initializer (in config/initializers)
require 'lib/foo_extension.rb'
चरण 3
There is no step 3 :)
रेल 5 विस्तार के लिए एक अंतर्निहित तंत्र प्रदान करता है ActiveRecord::Base
।
यह अतिरिक्त परत प्रदान करके हासिल किया गया है:
# app/models/application_record.rb
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
# put your extensions here
end
और सभी मॉडल उस से विरासत में मिले:
class Post < ApplicationRecord
end
इस ब्लॉग को देखें ।
बस इस विषय को जोड़ने के लिए, मैंने इस तरह के एक्सटेंशन का परीक्षण करने के लिए काम करते हुए बिताया (मैं ActiveSupport::Concern
मार्ग से नीचे चला गया ।)
यहां बताया गया है कि मैंने अपने एक्सटेंशन के परीक्षण के लिए एक मॉडल कैसे सेट किया।
describe ModelExtensions do
describe :some_method do
it 'should return the value of foo' do
ActiveRecord::Migration.create_table :test_models do |t|
t.string :foo
end
test_model_class = Class.new(ActiveRecord::Base) do
def self.name
'TestModel'
end
attr_accessible :foo
end
model = test_model_class.new(:foo => 'bar')
model.some_method.should == 'bar'
end
end
end
रेल 5 के साथ, सभी मॉडल ApplicationRecord से विरासत में मिले हैं और यह अन्य एक्सटेंशन लाइब्रेरीज़ को शामिल या विस्तारित करने का अच्छा तरीका देता है।
# app/models/concerns/special_methods.rb
module SpecialMethods
extend ActiveSupport::Concern
scope :this_month, -> {
where("date_trunc('month',created_at) = date_trunc('month',now())")
}
def foo
# Code
end
end
मान लें कि सभी मॉडलों में विशेष विधियों के मॉड्यूल उपलब्ध होने की आवश्यकता है, इसे application_record.rb फ़ाइल में शामिल करें। यदि हम इसे किसी विशेष मॉडल के सेट के लिए लागू करना चाहते हैं, तो इसे संबंधित मॉडल कक्षाओं में शामिल करें।
# app/models/application_record.rb
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
include SpecialMethods
end
# app/models/user.rb
class User < ApplicationRecord
include SpecialMethods
# Code
end
यदि आप मॉड्यूल को वर्ग विधियों के रूप में परिभाषित करना चाहते हैं, तो मॉड्यूल को ApplicationRecord तक बढ़ाएं।
# app/models/application_record.rb
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
extend SpecialMethods
end
आशा है कि यह दूसरों की मदद करे!
मेरे पास है
ActiveRecord::Base.extend Foo::Bar
इनिशियलाइज़र में
नीचे जैसे एक मॉड्यूल के लिए
module Foo
module Bar
end
end