1

私はUser多くを持つことができるを持っていRestaurantsます。複数のユーザーを持つこともできます。

ユーザーAがレストランAを作成した場合に、同じ名前の別のレストランを作成できないようにするために、これが必要です。

ただし、ユーザーBがレストランAを作成する場合は、許可する必要がありますが、後で別の レストラン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

owner.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.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>

実用的なソリューション

以下のRobertChuchroの助けのおかげで、検証を機能させることができました。これが私がしたことです:

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
4

1 に答える 1

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 かどうかを確認しますか? それを保存することを決定する前に。

于 2012-08-01T16:54:26.537 に答える