0

简短的问题...

如何在验证或保存之前编辑传递给模型的属性?


长问题...

在我的应用程序中,我有一个唯一编号生成器,以便可以在随机生成的唯一编号上对条目进行索引,这样用户就无法找到该条目(换句话说,使用 ID 的替代方法,用户可以随机猜测)。

所以在我的模型中,我有......

def self.generate_photo_number
  record = Object.new
  while record
    random = rand(9223372036854775806)
    record = Photo.first(:conditions => ["unique_photo_no = ?", random])
  end
  return random
end

在我的表格中,我有输入......

<%= hidden_field(:photo, :unique_photo_no, value: Photo.generate_photo_number) %>
i.e.
<input id="photo_unique_photo_no" name="photo[unique_photo_no]" type="hidden" value="233720368547758" />

问题是,如果用户提交表单,按下后退按钮,更改选项并再次提交,rails 应用程序将找到具有相同条目的条目unique_photo_no并导致保存错误。

我可以创建一个 JavaScript 函数,在单击提交时生成一个数字(我已经为 Rails 应用程序环境之外的页面完成了此操作),但该generate_photo_number函数的美妙之处在于它会检查以确保它不存在 - 而 JavaScript 确实不是。

如何在验证之前生成数字并将其保存在unique_photo_no属性中?

这就是我迄今为止在我的照片模型中放置的内容......

before_validation :generate_photo_number

validates_uniqueness_of :unique_photo_no,
                        :message => " - is already in use."

def self.generate_photo_number
  record = Object.new
  while record
    random = rand(9223372036854775806)
    record = Photo.first(:conditions => ["unique_photo_no = ?", random])
  end
  @photo.unique_photo_no = random
end
4

2 回答 2

0

一旦属性传递给模型,您将无法编辑该属性。

相反,在属性从控制器传递到模型之前对其进行编辑。


对于此问题示例,请执行以下操作...

  1. 删除 的表单输入字段unique_photo_no,因为不再需要它

  2. 将此添加到仅 Photos 控制器的“创建”操作中,在 @photo 实例变量下方。不要将其添加到“更新”操作中,否则每次更新都会生成一个新编号。

def create
  @photo = Photo.new(params[:photo])

  @photo.unique_photo_no = Photo.generate_photo_number

  .
  .
  .
end

照片(作为模型).generate_photo_number(作为被调用的函数)

于 2013-10-31T10:34:00.480 回答
0

Railscallbacks NOT a CLASS method 所以你需要在你的模型中删除 self 而不是我希望它会起作用。

如果您想在创建新记录时验证数据意味着您可以使用before_create callbacks

对于您的验证前回调应该在

before_validation :generate_photo_number

validates_uniqueness_of :unique_photo_no,
                        :message => " - is already in use."

def generate_photo_number
  record = Object.new
  while record
    random = rand(9223372036854775806)
    record = Photo.first(:conditions => ["unique_photo_no = ?", random])
  end
  self.unique_photo_no = random
end

当您点击保存或更新时,它会自动调用。

于 2013-10-31T10:49:02.237 回答