在迁移中:如何遍历模型并在Model中执行私有方法

时间:2011-06-09 10:23:28

标签: ruby-on-rails-3 migration

我有一个帖子,迁移会向其中添加新属性和表格列short_url。此属性由用户提供,如果留空,则自动创建:

class Post < ActiveRecord::Base
  before_create :create_short_url

  private
  def create_short_url
    if short_url.blank? || already_exists?(short_url)
      write_attribute :short_url, random_string(6)
    end
  end
  def random_string(length)
   #innards are irrelevant for this question
  end
end

在迁移中,我想浏览所有帖子并创建并保存short_url。

问题:由于create_short_url方法的私有范围,Post.find(:all).each {|post| post.create_short_url}中的self.up无效。

问题:通过帖子和update!循环播放它们不会调用before_create :create_short_url,因为它不是在创建之前。迁移后,我宁愿没有任何before_update挂钩:我不需要在更新时更改任何内容。

你会如何解决这个问题?将random_string()及相关方法复制到迁移中?将特定的迁移帮助程序方法添加到Post

1 个答案:

答案 0 :(得分:1)

只需使用Object方法send(它不会检查protected / private)。

Post.all.each do |post|
  post.send :create_short_url
  post.save!
end

另一种选择是(但这可能会干扰之后在同一个Ruby进程中运行的其他迁移):

Post.before_save :create_short_url
Post.all.each(&:save!)

可见性提示:大多数情况下,您的真正含义是protected(请参阅here)。在这种情况下,我建议使用protected代替private