7

関連コード: http://pastebin.com/EnLJUJ8G

class Task < ActiveRecord::Base
  after_create :check_room_schedule

  ...

  scope :for_date, lambda { |date| where(day: date) }
  scope :for_room, lambda { |room| where(room: room) }

  scope :room_stats, lambda { |room| where(room: room) }
  scope :gear_stats, lambda { |gear| where(gear: gear) } 

  def check_room_schedule
    @tasks = Task.for_date(self.day).for_room(self.room).list_in_asc_order
    @self_position = @tasks.index(self)

    if @tasks.length <= 2
      if @self_position == 0 
        self.notes = "There is another meeting in 
    this room beginning at # {@tasks[1].begin.strftime("%I:%M%P")}."
        self.save
      end
    end
  end

  private

    def self.list_in_asc_order
      order('begin asc')
    end
end

私は小さなタスクアプリを作っています。各タスクは部屋に割り当てられます。タスクを追加したら、コールバックを使用して、追加したばかりのタスクの前後に同じ部屋にタスクがあるかどうかを確認したいと思います (ただし、私のコードは現在 1 つのエッジ ケースしか処理していません)。

そこで、after_create を使用することにしました (編集する場合、ユーザーはこれを手動で確認するため、after_save ではありません)。2 つのスコープとクラス メソッドを使用して、その日の部屋でのタスクをクエリし、次の順序で並べ替えることができます。時間。次に、配列内のオブジェクトを見つけて、if ステートメントの使用を開始します。

オブジェクトを明示的に保存する必要があります。できます。しかし、私がそれをしているのは奇妙に感じます。私はあまり経験がないので(最初のアプリ)、これが嫌われているのか、慣例なのかわかりません。いろいろ調べたり、参考書を調べたりしましたが、これほど具体的なものはありませんでした。

ありがとう。

4

1 に答える 1

3

これは私にとって課題のように見えbefore_createます。コールバックに保存する必要がある場合はafter_*、おそらくbefore_*代わりにコールバックを使用するつもりでした。

コールバック コードが実行された後に保存が行われるため、before_createを呼び出す必要はありません。save

また、保存してからクエリを実行して 2 つ以上のオブジェクトが返されるかどうかを確認するのではなく、保存する前に衝突する 1 つのオブジェクトをクエリする必要があります。

疑似コードでは、あなたが今持っているもの:

after creation
  now that I'm saved, find all tasks in my room and at my time
  did I find more than one?
    Am I the first one?
      yes: add note about another task, then save again
      no: everything is fine, no need to re-save any edits

あなたが持っているべきもの:

before creation
  is there at least 1 task in this room at the same time?
    yes: add note about another task
    no: everything is fine, allow saving without modification

このようなもの:

before_create :check_room_schedule
def check_room_schedule
  conflicting_task = Task.for_date(self.day)
                         .for_room(self.room)
                         .where(begin: self.begin) # unsure what logic you need here...
                         .first
  if conflicting_task
    self.notes =
      "There is another meeting in this room beginning at #{conflicting_task.begin.strftime("%I:%M%P")}."
  end
end
于 2012-09-24T19:24:04.910 に答える