私の意図は、スタッフと臨床家の2種類でSTIを実装することです。私の以前の実装では列挙型でロールを使用していましたが、同様の質問への回答に従うように最善を尽くした後、テストなどですべての参照を取り出してロールに列挙し、型への参照で置き換えました。私のテストスイートを実行します。ここでは単一テーブルの継承エラー - ActiveRecord :: SubclassNotFound
ERROR["test_valid_signup_information_with_account_activation", UsersSignupTest, 1.01794000000001]
test_valid_signup_information_with_account_activation#UsersSignupTest (1.02s)
ActiveRecord::SubclassNotFound: ActiveRecord::SubclassNotFound: The single-table inheritance mechanism failed to locate the subclass: 'Staff'. This error is raised because the column 'type' is reserved for storing the class in case of inheritance. Please rename this column if you didn't intend it to be used for storing the inheritance class or overwrite User.inheritance_column to use another column for that information.
app/controllers/users_controller.rb:19:in `create'
test/integration/users_signup_test.rb:27:in `block (2 levels) in <class:UsersSignupTest>'
test/integration/users_signup_test.rb:26:in `block in <class:UsersSignupTest>'
は、私は、潜在的な問題に隠れことができることが混乱していますカップルのエリアです:私のユーザーモデルuser.rbで
を、私は(私が正しく、サブクラスを定義していますだと思いますスタッフと臨床家)が、私はすべてを正しくラッピングしているかどうかは分かりません。他のすべてのコードは、これらのクラスのいずれかに含まれていなければなりませんか?私は「終わり」を悪用していますか?
class User < ApplicationRecord
end
class Staff < User
end
class Clinician < User
end
belongs_to :university
has_many :referral_requests
attr_accessor :remember_token, :activation_token, :reset_token
before_save :downcase_email
before_create :create_activation_digest
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.][email protected][a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
validates :type, presence: true
validates :university_id, presence: true, if: lambda { self.type == 'Staff' }
has_secure_password
validates :password, presence: true, length: { minimum: 6 }, allow_nil: true
# 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
# Returns a random token.
def User.new_token
SecureRandom.urlsafe_base64
end
# Remembers a user in the database for use in persistent sessions.
def remember
self.remember_token = User.new_token
update_attribute(:remember_digest, User.digest(remember_token))
end
# Returns true if the given token matches the digest.
def authenticated?(remember_token)
return false if remember_digest.nil?
BCrypt::Password.new(remember_digest).is_password?(remember_token)
end
# Forgets a user.
def forget
update_attribute(:remember_digest, nil)
end
# Returns true if the given token matches the digest.
def authenticated?(attribute, token)
digest = send("#{attribute}_digest")
return false if digest.nil?
BCrypt::Password.new(digest).is_password?(token)
end
# Activates an account.
def activate
update_attribute(:activated, true)
update_attribute(:activated_at, Time.zone.now)
end
# Sends activation email.
def send_activation_email
UserMailer.account_activation(self).deliver_now
end
# Sets the password reset attributes.
def create_reset_digest
self.reset_token = User.new_token
update_attribute(:reset_digest, User.digest(reset_token))
update_attribute(:reset_sent_at, Time.zone.now)
end
# Sends password reset email.
def send_password_reset_email
UserMailer.password_reset(self).deliver_now
end
# Returns true if a password reset has expired.
def password_reset_expired?
reset_sent_at < 2.hours.ago
end
def feed
ReferralRequest.where("user_id = ?", id)
end
private
# Converts email to all lower-case.
def downcase_email
self.email = email.downcase
end
# Creates and assigns the activation token and digest.
def create_activation_digest
self.activation_token = User.new_token
self.activation_digest = User.digest(activation_token)
end
end
ここで失敗している特定のテストコード( - すべてのユーザーパラメータが同様にかかわらず定義されて失敗しているテストスイートの多くのもの)です。 staffパラメーターを適切に渡していますか?任意のアイデアを
create_table "users", force: :cascade do |t|
t.string "name"
t.string "email"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "password_digest"
t.string "remember_digest"
t.string "activation_digest"
t.boolean "activated", default: false
t.datetime "activated_at"
t.string "reset_digest"
t.datetime "reset_sent_at"
t.integer "university_id"
t.integer "role"
t.string "type"
t.index ["email"], name: "index_users_on_email", unique: true
end
どうもありがとうございました:
test "valid signup information with account activation" do
get signup_path
assert_difference 'User.count', 1 do
post users_path, params: { user: { name: "Example User",
email: "[email protected]",
university_id: 1 ,
type: "Staff",
password: "password",
password_confirmation: "password" } }
は、ここに私のユーザーテーブルスキーマです!私はここで多くの質問をしますが、それはかなりの間、同様の回答を処理しようとした後です。
コードサンプルは、右限りです。あなたの有益なフィードバックに基づいて明らかに間違っています。私は実装します。ありがとう! – mike9182
1つの質問:STIへの切り替えで新しい構文に消化するなどの方法を変更する必要があるのはなぜですか?私はあなたを信じています。私はそれを確かに書くことができますが、なぜそれが変わったのか分かりません。 – mike9182
@ mike9182はSTIとは関係がありません。それはRubyの書いたとおりです。私はあなたが働いていると思っていますが、私が与えた例は、他のRubyの人々が期待するものです。 –