使用after_find回调覆盖nil值

时间:2011-08-09 00:07:55

标签: ruby-on-rails ruby database ruby-on-rails-3 activerecord

现在我有一个用于存储配置文件数据的Rails 3模型。如果用户选择显示个人资料图片,则该数据库表中的一列包含图像网址(如果他们使用Facebook登录但这与用户的个人资料图片网址相关,则该图片网址也存储该用户的个人资料图片网址)。我遇到的问题是,当image列为nil时,我需要一种方法将其设置为我服务器上的默认路径。请注意,我不能在此处使用迁移或模型中的默认值。我的想法是使用after_find,但以下不起作用:

在个人资料模型中:

  def after_find
    if self.image.nil?
      self.image = "/assets/generic_profile_image.png"
    end
  end

在视野中(HAML):

.profile_pic
    = image_tag @user.profile.image

Profile模型通过has_one关联链接到User模型。现在,而不是动态地将图像属性转换为“/assets/generic_profile_image.png”,似乎什么都没有让我在页面上生成以下生成的代码:

    <div class='profile_pic'>
      <img alt="Assets" src="/assets/" />
    </div>

非常感谢有关如何解决此问题的任何建议!

P.S。视图中的条件是不可能的,因为配置文件图像显示的方式太多了!

2 个答案:

答案 0 :(得分:3)

只需在模型中创建条件并在视图中引用它。

class User
  delegate :image, :to => :profile, :prefix => true, :allow_nil => true

  def picture_url
    if profile_image.present?
      profile_image
    else
      "/assets/generic_profile_image.png"   
    end
  end
end

我喜欢这种方法,因为当您想要更改默认图片时,不必运行SQL查询。

我添加了代表,以防止破坏德米特定律。

当然,您已经猜到了视图代码:

.profile_pic
    = image_tag @user.picture_url       

答案 1 :(得分:1)

我的猜测是你的after_find回调实际上没有被调用。您需要以这种方式定义它:

class Profile < ActiveRecord::Base
  after_find :update_image

  def update_image
    if self.image.nil?
      self.image = "/assets/generic_profile_image.png"
    end
  end
end

现在一切都应该正常。