0

我想要一些关于如何处理to_param的建议permalinks

基本上这就是发生的事情。

  • 创建新公司
  • 然后将公司:name参数化并保存为:permalink数据库中的
  • 更新现有公司使您能够更改:permalink
  • 有验证以确保用户更新:permalink是唯一的

我遇到的问题是在将公司更新为:permalink已经存在的东西时发生的。唯一性验证非常有用,但它会将永久链接更改params[:id]为无效的永久链接,而不是重置和使用现有的params[:id]

当我尝试将其编辑permalink为其他内容时,我收到一个 Flash 验证错误,"Name already taken"因为它认为我正在编辑现有:permalink(公司)的公司。该 URL 反映了permalink自从我companies_controller.rb使用以来的变化@company = Company.find_by_permalink[:id])

我想知道处理这个问题的最佳方法?

class Companies < ActiveRecord::Base
  before_create :set_permalink
  before_update :update_permalink

  attr_accessible :name, :permalink

  validates :name, :permalink, uniqueness: { message: 'already taken' }

  def to_param
    permalink
  end

  private

  def set_permalink_url
    self.permalink = name.parameterize
  end

  def update_permalink_url
    self.permalink = permalink.parameterize
  end


end

抱歉,如果我没有太多意义。

提前致谢。

4

1 回答 1

0

after_rollback你可以尝试通过回调来处理这个问题。

 after_rollback :restore_permalink

 def restore_permalink
   self.permalink = permalink_was if permalink_changed?
 end

它是这样工作的:Rails 中的每个更新/销毁都包含在一个事务中。如果保存失败,事务回滚并触发回调。permalink_was如果在加载记录后发生更改,则回调将恢复旧值 ( )。

有关详细信息,请参阅ActiveModel::DirtyActiveRecord::Transactions

编辑

另一方面,可能还有另一种解决方案(未经测试) - 只需像这样定义您的访问器:

 def permalink=( value )
   permalink_will_change! unless @permalink == value
   @permalink = value
 end

这样,如果新值与旧值相同,则永久链接不会被标记为脏,因此 AR 不会尝试更新列。

解释:

我不知道它是在哪个版本的 Rails 上实现的(它是相对较新的),但这是“脏”的工作原理:

  • 您的“标准”(自动生成)属性设置器基本上 #{your_attribute}_will_change!在设置关联的实例变量之前调用(即使您设置的值与以前完全相同)
  • 当您调用时save,ActiveRecords 会查找已更改的属性(“脏”)并仅使用这些属性构建 SQL UPDATE 查询(主要是出于性能原因)
  • 因此,如果您想避免您的永久链接在未更改时出现在查询中,我认为您必须覆盖标准设置器 - 或避免批量分配并且仅permalink在它已更改时设置
于 2012-11-10T17:27:53.897 回答