0

我在这个Railscast之后设置了一个自动完成关联。

我正在使用find_or_initialize而不是find_or_create在虚拟 category_name 属性上,因为我需要通过其他一些逻辑传递值。

如果父模型验证失败(railscast 中的产品),保持此虚拟属性的最佳方法是什么。category_name如果出现错误,我希望在保存路径呈现表单后保留用户输入的内容。

我认为可以通过 访问该值params[:category_name],但我无法将其设置回该字段。

感谢任何想法。

编辑

控制器

class ProductsController < ApplicationController

  ...

  def create
    @product = current_user.products.build(params[:prerep])

    if @products.save
      DO SOME STUFF...

      respond_to do |format|
        format.html { redirect_to(@product, :notice => 'Product was successfully created.') }
        format.xml  { render :xml => @product, :status => :created, :location => @product }
      end

    else
      respond_to do |format|
        format.html { render :action => "new" }
        format.xml  { render :xml => @product.errors, :status => :unprocessable_entity }
      end
    end
  end
end

模型:

class Prerep < ActiveRecord::Base
  attr_accessible ..., :category_name, ... 
  attr_reader ...
  attr_accessor ...

  belongs_to :user, :category

  has_many ...

  validates ...

  def category_name
    category.try(:name)
  end  

  def category_name=(name)
    product_category = Category.find_or_initialize_by_name(name) if name.present?
    self.category = if product_category.new_record?
      product_category ...SET SOME ATTRIBUTES...
      product_category.save(:validate => false)
      product_category
    else
      product_category
    end
  end
end
4

1 回答 1

0

我想我会回答这个问题,因为我遇到了完全相同的问题,但我找不到一个答案。

最好的方法是手动验证您需要验证的所有内容。validates因此,您必须自己在控制器中进行,而不是让过滤器来做。因此,如果您的属性是用户名、电话和电子邮件,请不要validates :email, presence: true在模型中执行,而是在控制器中手动执行。这样,如果你有额外的参数,你可以在你的控制器或它的助手中添加另一个验证方法来进行验证,它让你有机会坚持这个。

希望这可以节省人们的时间,因为似乎没有更简单的方法来解决问题。我的意思是,无论如何,rails 已经大大加快了我们的开发时间,再多几行代码不会杀死我们;)

于 2014-02-21T19:50:25.337 回答