1

私がStatementモデルを持っているとしましょうhas_many :months。ステートメントには常に12か月が関連付けられていますが、最初の月は異なる場合があります(たとえば、月= [3月、4月、5月... 1月、2月])

特定の月が与えられた場合、前月を見つけるための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データベースに列を含める必要がありますか?この機能をどのように実装しますか?Railsを使用しています2.3.x

4

3 に答える 3

1

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。これは、保存されていないレコードでも機能するはずです。

于 2010-11-07T21:08:20.257 に答える
0

これらの月はどのように追加されますか?それらが月の時系列で別々に追加される場合、あなたは単にあなたが持っていることをすることができますが、あなたは関係の中で順序を定義するべきです。

#statement.rb

has_many :months, :order => 'created_at ASC'

それらが他の方法で追加された場合は、注文列を作成し、acts_as_listを使用して注文を維持することを検討する必要があります。

于 2010-11-07T20:54:59.647 に答える
0

これを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
于 2010-11-24T02:56:49.973 に答える