关于ruby:在Rails应用程序中验证唯一字段

Validate unique field in Rails app

在我的Rails应用程序中,我有两个模型-UserAccount

一个User可以有许多Accounts

Account包含一个name字段,如下图所示。

如何验证name字段对于Account是唯一的,但在数据库中不一定是唯一的?例如,User1可以具有名称为CashAccount,而User2可以具有不同的Account但名称为Cash

user.rb:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class User < ActiveRecord::Base
  has_many :accounts

  before_save { self.email = email.downcase }

  VALID_EMAIL_REGEX = /\\A[\\w+\\-.]+@[a-z\\d\\-.]+\\.[a-z]+\\z/i

  validates :email, presence: true,
                    length: { maximum: 255 },
                    format: { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }

  has_secure_password

  validates :password, presence: true, length: { minimum: 6 }

  # Returns the hash digest of the given string.
  def User.digest(string)
    cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
                                                  BCrypt::Engine.cost
    BCrypt::Password.create(string, cost: cost)
  end
end

account.rb:

1
2
3
4
5
6
7
8
9
10
11
class Account < ActiveRecord::Base
  belongs_to :user
  has_many :balances

  before_save { self.active = true }

  validates :name, presence: true, length: { maximum: 250 },
                  uniqueness: { case_sensitive: false }

  validates :user, presence: true
end

schema.rb:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  ....
  create_table"accounts", force: :cascade do |t|
    t.string  "name"
    t.boolean "credit"
    t.boolean "active",     default: true, null: false
    t.datetime"created_at",                null: false
    t.datetime"updated_at",                null: false
    t.integer "user_id"
  end

  create_table"balances", force: :cascade do |t|
    t.decimal "balance"
    t.date    "date"
    t.integer "account_id"
    t.datetime"created_at", null: false
    t.datetime"updated_at", null: false
  end

  create_table"users", force: :cascade do |t|
    t.string  "email"
    t.boolean "admin"
    t.datetime"created_at",      null: false
    t.datetime"updated_at",      null: false
    t.string  "password_digest"
  end

  add_index"users", ["email"], name:"index_users_on_email", unique: true
  ....


您可以使用scope

您的account.rb

中的

1
validates :name, uniqueness: { scope: :user_id}

您实际验证的四个:

1
2
  validates :name, presence: true, length: { maximum: 250 },
                  uniqueness: { case_sensitive: false, scope: :use_id }

活动记录验证