我正在尝试为我的管理模型设置设计。 admin模型继承自Author。我已完成文档中建议的所有设计设置并运行所有迁移等。我的模型如下:
作者类:
class Author < ActiveRecord::Base
has_many :articles
validates :first_name, :surname, :email, presence: true
end
管理员类:
class Admin < Author
devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable
end
设计迁移:
class DeviseCreateAdmins < ActiveRecord::Migration
def change
create_table(:admins) do |t|
## Database authenticatable
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, default: 0, null: false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.inet :current_sign_in_ip
t.inet :last_sign_in_ip
## Confirmable
# t.string :confirmation_token
# t.datetime :confirmed_at
# t.datetime :confirmation_sent_at
# t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
# t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
t.timestamps null: false
end
add_index :admins, :email, unique: true
add_index :admins, :reset_password_token, unique: true
#add_index :admins, :confirmation_token, unique: true
#add_index :admins, :unlock_token, unique: true
end
在DB中显示encrypted_password
的架构。
create_table "admins", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
尝试在我的某个测试或rails控制台中创建管理员时收到的错误如下:
NoMethodError:
undefined method `encrypted_password=' for #<Admin:0x007fc1c3269e18>
使用的测试是:
scenario 'Signing in with correct credentials' do
Admin.create(first_name: "Jonathan", surname: "Sayer", email: "test@email.com",
password: "password", password_confirmation: "password")
visit '/login'
fill_in 'Email', with: "test@email.com"
fill_in 'Password', with: "password"
click_button "Log in"
expect(page.current_path).to eq root_path
end
显示错误消息:
1) Signing in Signing in with correct credentials
Failure/Error:
Admin.create(first_name: "Jonathan", surname: "Sayer", email: "test@email.com",
password: "password", password_confirmation: "password")
NoMethodError:
undefined method `encrypted_password=' for #<Admin:0x007fc1c3269e18>
# /Users/jonathansayer/.rvm/gems/ruby-2.3.0/gems/devise-3.5.6/lib/devise/models/database_authenticatable.rb:43:in `password='
# ./spec/features/logging_in_and_out_spec.rb:5:in `block (2 levels) in <top (required)>'
任何帮助都将非常感谢!!感谢
答案 0 :(得分:0)
Solution
Add self.table_name = "admins"
to your Admin
model to fix the error.
Explanation
I see that the Admin
model is inherited from the Author
model. Which btw is not recommended unless you are trying to implement STI (single table inheritance).
Which is not the case here as you have tables for both the models. And here lies the actual problem.
You see by default ActiveRecord connects a Rails model to it's corresponding table in the DB using the pluralized name of the model.
So in this case for the Author
model it corresponds to the authors
table in the DB. Now since Admin
is inherited from Author
it too is connected to authors
table.
And that is why all the fields you expect to be present in the admins
table is not present. Because right now the Admin
model knows only the fields in authors
table
The fix would be to explicitly specify the table name for the model.