Rails - 使用before_filter运行方法

时间:2013-01-02 22:22:27

标签: ruby-on-rails ruby methods before-filter

我希望在每次加载页面(现在)之前运行过滤器以检查项目是否超过7天,如果是,请在其上运行一些操作以更新其属性。

我在应用程序控制器中有before_filter :update_itupdate_it定义如下:在同一个控制器中:

def update_it
  @books = Book.all
  @books.each do |book|
    book.update_queue
  end
end

然后在书模型中定义update_queue。以下是模型中与此相关的所有内容:

scope :my_books, lambda {|user_id|
    {:conditions => {:user_id => user_id}}  
  }

  scope :reading_books, lambda {
    {:conditions => {:reading => 1}}
  }

  scope :latest_first, lambda {
    {:order => "created_at DESC"}
  }


  def move_from_queue_to_reading
    self.update_attributes(:queued => false, :reading => 1);
  end

  def move_from_reading_to_list
    self.update_attributes(:reading => 0);
  end

  def update_queue
    days_gone = (Date.today - Date.parse(Book.where(:reading => 1).last.created_at.to_s)).to_i

    # If been 7 days since last 'currently reading' book created
    if days_gone >= 7

        # If there's a queued book, move it to 'currently reading'
        if Book.my_books(user_id).where(:queued => true)
            new_book = Book.my_books(user_id).latest_first.where(:queued => true).last
            new_book.move_from_queue_to_reading
            currently_reading = Book.my_books(user_id).reading_books.last
            currently_reading.move_from_reading_to_list

        # Otherwise, create a new one
        else
            Book.my_books(user_id).create(:title => "Sample book", :reading => 1)

        end
    end
  end

我的关系是一本书属于一个用户,一个用户拥有多本书。我通过用户节目视图在视图中显示这些书籍,但并不重要。

所以我不断得到的错误是move_from_queue_to_readingmove_from_reading_to_list是未定义的方法。怎么会这样?我清楚地定义它们然后在下面调用它们。我真的很茫然,非常欣赏我对错误的看法。我是初学者,所以任何有条理的批评都会很棒:)

修改

我得到的确切错误消息和堆栈跟踪如下:

NoMethodError in UsersController#show
undefined method `move_from_queue_to_reading' for nil:NilClass

app/models/book.rb:41:in `update_queue'
app/controllers/application_controller.rb:22:in `block in update_it'
app/controllers/application_controller.rb:21:in `each'
app/controllers/application_controller.rb:21:in `update_it'

1 个答案:

答案 0 :(得分:1)

我怀疑返回的集合是一个空数组(测试时仍然是'truthy')。因此,调用.last会将nil返回到new_bookcurrently_reading局部变量。尝试更改:

if Book.my_books(user_id).where(:queued => true)

为:

if Book.my_books(user_id).where(:queued => true).exists?

此外,您在查找currently_reading时正在修改范围。这可能会导致查询再次返回无结果。变化:

currently_reading.move_from_reading_to_list

为:

currently_reading.move_from_reading_to_list if currently_reading