ما هي طريقة القضبان للوصول إلى السجل السابق في سلسلة؟

StackOverflow https://stackoverflow.com/questions/4119582

سؤال

قل لدي 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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top