0

私は現在、この最初の詳細なコードを乾かそうとしています。

def planting_dates_not_nil?
    !plant_out_week_min.blank? || !plant_out_week_max.blank? || !sow_out_week_min.blank? || !sow_out_week_max.blank?
  end

  def needs_planting?(week)
    if !plant_out_week_min.blank? && !plant_out_week_max.blank?
      (plant_out_week_min..plant_out_week_max).include? (week) 
    end
  end

  def needs_sowing?(week)
    if !sow_out_week_min.blank? && !sow_out_week_max.blank?
      (sow_out_week_min..sow_out_week_max).include? (week)
    end 
  end

  def needs_harvesting?(week)
    if !harvest_week_min.blank? && !harvest_week_max.blank?
      (harvest_week_min..harvest_week_max).include? (week) 
    end
  end

これが私の最初の試みです:

  def tasks_for_week(week,*task_names)
    task_names.each do |task_name|
      to_do_this_week = []
        unless read_attribute(task_name).nil?
          if (read_attribute("#{task_name}_week_min")..read_attribute("#{task_name}_week_max")).include? (week)
            to_do_this_week << task_name
          end
        end
      end
  end

ただし、このコードをコンソールで次のように実行すると、次のようになります。

p.tasks_for_week(Date.today.cweek, :plant_out, :sow_out])

予期しない結果が発生します...植物を植え付ける必要はありませんが、両方のタスク名の配列が返されます([:plant_out、:sow_out]

誰かがこれをクリーンアップしてtasksforweekメソッドに期待される結果を返す方法を教えてもらえますか?

TIA

4

3 に答える 3

1

上記で注意すべきことの 1 つはself[task_name]、作成したカスタム getter メソッドを無視して、データベースから生データを取得しているように見えることです。

カスタム ゲッターを使用する場合、または属性として扱いたいメソッドがある場合は、self.send(task_name)代わりにself[task_name].

于 2009-02-15T01:53:54.080 に答える
1

あなたのメソッドは の結果を返していtask_names.eachます。 eachは、常にそれが開始したものを返します。したがって、実際に結果を返す必要があります。

また、to_do_this_weekループの反復ごとに配列を再作成しているため、きれいに消去されます。

def tasks_for_week(week, *task_names)
  to_do_this_week = []
  task_names.each do |task_name|
    if some_condition
      to_do_this_week << task_name 
    end
  end
  to_do_this_week
end

またはこれ:

def tasks_for_week(week, *task_names)
  returning [] do |to_do_this_week|
    task_names.each do |task_name|
      if some_condition
        to_do_this_week << task_name 
      end
    end
  end
end

しかし、これはおそらくあなたの最高のものだと思います:

def tasks_for_week(week, *task_names)
  task_names.find_all do |task_name|
    some_condition
  end
end

最後の 1 つはfind_all、配列を反復処理する which を使用し、ブロックが true 値を返すすべてのオブジェクトが取り込まれた新しい配列を返します。

最後に、条件付きロジックも少しクレイジーです。[]動的な方法でアクティブなレコード フィールドのアクセサーを使用できます。通常は、 の二重否定の代わりに肯定のケースを使用する方が明確ですunless something.nil?。これが範囲を作成するための一般的な用途である場合は、それをメソッドにファームアウトするのが最善かもしれません:

def week_range_for_task(task)
  self["#{task_name}_week_min"]..self["#{task_name}_week_max"]
end

...

self[task_name] && week_range_for_task(task_name).include?(week)

メソッド全体の作成:

def tasks_for_week(week, *task_names)
  task_names.find_all do |task_name|
    self[task_name] && week_range_for_task(task_name).include?(week)
  end
end
于 2009-02-14T23:51:54.293 に答える
0

これは、そこに新しい条件メソッドを含むわずかに修正されたコードです。

  def whole_range_exists?(method_name)
        self["#{method_name}_week_min"] && self["#{method_name}_week_max"]
      end

      def week_range_for_task(task_name)
        self["#{task_name}_week_min"]..self["#{task_name}_week_max"]
      end

      def tasks_for_week(week, *task_names)
        task_names.find_all do |task_name|
          whole_range_exists?(task_name) && week_range_for_task(task_name).include?(week)
        end
      end
于 2009-02-15T15:05:31.683 に答える