做双列验证的好方法

时间:2010-12-21 10:56:01

标签: ruby-on-rails validation ruby-on-rails-3

我正在使用Rails 3。我有一个集合模型,一个用户模型和一个中间订阅模型。这样,用户可以订阅具有特定角色的多个集合。但是,我不希望用户能够两次订阅同一个集合。

所以在我的订阅模型中,我有类似的东西:

validate :subscription_duplicates

def subscription_duplicates
  self.errors.add_to_base "This user is already subscribed" if Subscription.where(:user_id => self.user.id, :collection_id => self.collection.id)
end

然而这看起来很难看。此外,当我想在我的集合控制器中执行以下操作时,它会中断:

def create
  @collection = Collection.new(params[:collection])
  @collection.subscriptions.build(:user => current_user, :role => Subscription::ROLES['owner'])
  @collection.save
  respond_with(@collection)
end

当我进行构建时,订阅没有id,所以我得到一个“为nil调用id”错误。

感谢任何指导!

2 个答案:

答案 0 :(得分:3)

使用validates_uniqueness_of

validates_uniqueness_of :user_id, :scope => :collection_id

答案 1 :(得分:0)

首先,您的创建操作应始终测试对象是否已保存,如果没有,则应处理(通常通过重新呈现新/编辑页面并向用户显示错误)。

标准类型的创建操作将如下所示(在这种情况下为@post):

def create
  @post = Post.new(params[:post])
  @created = @post.save
  respond_to do |format|
    if @created
      flash[:notice] = 'Post was successfully created.'
      format.html { redirect_to @post }
      format.xml  { render :xml => @post, :status => :created, :location => @post }
      format.js
    else
      format.html { render :action => :new } #or edit or wherever you got here from
      format.xml  { render :xml => @post.errors, :status => :unprocessable_entity }
      format.js
    end
  end
end 

Shingara避免重复的方法应该适合你。