【问题标题】:validating uniqueness within a has_many through通过在 has_many 中验证唯一性
【发布时间】:2012-07-30 14:51:15
【问题描述】:

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

我想拥有它,以便如果用户 A 创建 餐厅 A,他应该可以再开一家同名餐厅。

但是,如果用户 B 去创建 Restaurant A,应该允许但仍然不能创建 另一个 Restaurant A 之后。

我有以下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 => true

我已经尝试将 :uniq => true 添加到 restaurant.rb 文件,所以它看起来像这样:

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

并从验证中删除uniqueness: true,使其看起来像这样:

validates :name, presence: true

但这并没有什么用处。

2。在 owner.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

【问题讨论】:

  • 你试过什么?您当前的代码是什么?你到底卡在哪里了?你遇到什么错误?
  • @Jocelyn 我已经更新了我上面的帖子,以展示我尝试过的一些事情。

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


【解决方案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 是否存在?在决定保存之前。

【讨论】:

  • 我尝试了您所说的内容,但出现错误。我已经更新了我原来的帖子。您能否在“我尝试过的内容”部分下看到 #3 并给我一些指示?谢谢!
  • 你需要问号吗?在 before_create :check_uniqueness?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多