ما هي طريقة القضبان للوصول إلى السجل السابق في سلسلة؟
-
29-09-2019 - |
سؤال
قل لدي Statement
النموذج ، الذي has_many :months
. هناك دائمًا 12 شهرًا مرتبطة ببيان ، لكن يمكن أن يختلف الشهر الأول (على سبيل المثال شهور = [مارس ، أبريل ، مايو ... يناير ، فبراير])
بالنظر إلى شهر معين ، ما هي طريقة MVC للعثور على الشهر السابق؟
أجد نفسي وصوله من خلال statement
الذي يشعر بالقلق:
# statement.rb
has_many :months
def previous_month(month)
if months.index(month) == 0
return nil
else
return months[months.index(month) - 1]
end
end
# blergh
prev_month = month.statement.previous_month(month)
هل يجب أن يكون لدي ملف previous_month_id
العمود في قاعدة البيانات الخاصة بي؟ كيف يمكنك تنفيذ هذه الوظيفة؟ أنا أستخدم القضبان 2.3.x
.
المحلول
أود تحديده على Month
نموذج لتقليص على المائدة المستديرة.
# month.rb
class Month < ActiveRecord::Base
belongs_to :statement, :include => :months
def previous
return nil if self.index == 0
find_or_create_by_index_and_statement_id(self.index - 1, self.statement.id)
end
def index
statement.months.index self
end
end
حتى تتمكن من الحصول عليها june.previous
. هذا يجب أن يعمل حتى على السجلات غير المحفوظة.
نصائح أخرى
كيف تتم إضافة هذه الأشهر؟ إذا تمت إضافتها بشكل منفصل بالترتيب الزمني للأشهر ، فيمكنك ببساطة القيام بما لديك ولكن يجب عليك تحديد الترتيب في العلاقة.
#statement.rb
has_many :months, :order => 'created_at ASC'
إذا تمت إضافتها بطريقة أخرى ، فقد تحتاج إلى التفكير في وجود عمود طلب واستخدام ACTS_AS_LIST للحفاظ على الترتيب.
للقيام بذلك ، طريقة MVC ، ربما دفع هذا المنطق على الشيء الذي "يمتلك" العبارات. بعد كل شيء عادة ما ينتمي إلى شيء ما. بعد قراءة التعليقات ، يبدو أن هذا مشروع ورث. إذا لم يكن عليك أن تسأل لماذا سيكون لديك علاقة "أشهر" ، عندما يكون للبيان أ created_at
عمود يمكنك ربطه؟ إليكم ما توصلت إليه ، قد لا يكون مفيدًا لك. على الرغم من عدم الخروج Date::MONTHNAMES
على الأقل يبدو أن هذا قد يكون مفيدًا لك.
describe User do
before(:each) do
@user = User.create!
end
it "should know about months" do
Statement.create(:user => @user)
@user.statements.last.month_name.should == "November"
end
it "should report last months statement as nil when there is no statement" do
@user.last_months_statement.should be_nil
end
it "should report last months statement as nil if there is only one for this month" do
Statement.create(:user => @user)
@user.last_months_statement.should be_nil
end
it "should report a statement from the previous month if there is one" do
target = Statement.create(:user => @user, :created_at => 1.month.ago)
Statement.create(:user => @user)
@user.last_months_statement.should == target
end
it "should report last months statement if there a several" do
Statement.create(:user => @user, :created_at => 1.month.ago)
Statement.create(:user => @user)
Statement.create(:user => @user, :created_at => 2.months.ago)
@user.last_months_statement.month_name.should == "October"
end
end
class User < ActiveRecord::Base
has_many :statements, :order => "created_at"
def last_months_statement
if statements.size <= 1 || statements.last.created_at.month < Time.now.month
nil
else
index = statements.index(statements.last)
statements[index - 1]
end
end
end
class Statement < ActiveRecord::Base
belongs_to :user
def month
created_at.month
end
def month_name
Date::MONTHNAMES[created_at.month]
end
end