验证has_many中的唯一性

时间:2012-08-01 16:42:41

标签: mysql ruby-on-rails validation has-many-through

我有User,可以有很多Restaurants。我也可以有多个用户。

我希望如果用户A 创建餐厅A ,他应该 能够建立另一家同名餐厅。

但是,如果用户B 去创建餐厅A ,则应该允许这样做但仍然无法使另一个 餐厅A < / strong>之后。

我有以下has_many through关系:

restaurant.rb

has_many :ownerships
has_many :users, :through => :ownerships

# This following ensures uniqueness of the name within the 
#   Restaurants table regardless of who the User is that created it.
validates :name, presence: true, uniqueness: true

user.rb

has_many :ownerships
has_many :restaurants, :through => :ownerships

ownership.rb

belongs_to :restaurant
belongs_to :user

我尝试过什么

1。添加:uniqu =&gt;真

我尝试添加:uniq =&gt;对于restaurant.rb文件是true,所以看起来像这样:

has_many :ownerships
has_many :users, :through => :ownerships, :uniq => true

从验证中删除uniqueness: true,使其如下所示:

validates :name, presence: true

但这没有任何用处。

2。在ownership.rb中添加验证

我已尝试将验证添加到ownership.rb文件中:

validates :restaurant, uniqueness: {:scope => :user}

但我明白了:

NoMethodError in RestaurantsController#create
undefined method `text?' for nil:NilClass

我似乎无法告诉它在此验证范围内查找用户范围内的餐馆名称。

第3。创建before_create回调函数

在我的restaurant.rb文件中,我声明了以下内容:

before_create :check_uniqueness

def check_uniqueness?
  user = User.find_by_id(self.user_ids)

  isUnique = false
  user.restaurants.each do |restaurant|
    if !Restaurant.find_by_name(self.name).nil? # Restaurant w/ same now found
      isUnique = false
    else
      isUnique = true
    end
    return isUnique
  end
end

我的假设是,在创建餐馆记录之前,它会执行此check_uniqueness检查,如果该函数返回false,则不会保存。

但是当我点击提交按钮时出现以下错误:

NameError in RestaurantsController#create
undefined local variable or method `check_uniqueness' for #<Restaurant:0x007f95a16d10f8>

工作解决方案

感谢Robert Chuchro's help below,我能够让验证工作。这是我做的:

restaurant.rb

before_create :unique_per_user?

def unique_per_user?
  user = User.find_by_id(self.user_ids)
  restaurant = user.restaurants.find(:all, :conditions => ["name = ?", self.name])

  if restaurant.size > 0
    self.errors.add(:name, ": You've already created a restaurant with this name.")
  end

  return (restaurant.size <= 0)
end

1 个答案:

答案 0 :(得分:1)

您可以尝试在餐厅模型中定义一种方法

def unique_per_user?
  #get user trying to create restaurant, either by paramter or association
  #check if any of the user's current restaurant names match this name (return true/false)
end

现在,如果你定义一个新的餐厅检查它的unique_per_user?在决定保存之前。