我正在创建许可证服务器,但我遇到了问题,那就是Rails无法保存模型。
我在after_create
模型中设置了User
方法,但是没有运气,我也尝试使用Rails控制台创建License
模型,但是它回滚事务并且没有显示任何错误。
models / user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable,
authentication_keys: [:login]
attr_writer :login
has_one :license, dependent: :destroy
validates :username, presence: true, uniqueness: { case_sensitive: false }
validates_format_of :username, with: /^[a-zA-Z0-9_\.]*$/, multiline: true
after_create :create_assocs
def login
@login || self.username
end
def self.find_first_by_auth_conditions(warden_conditions)
conditions = warden_conditions.dup
if login = conditions.delete(:login)
where(conditions).where(['lower(username) = :value OR lower(email) = :value', { value: login.downcase }]).first
else
if conditions[:username].nil?
where(conditions).first
else
where(username: conditions[:username]).first
end
end
end
def email_required?
false
end
private
def create_assocs
create_license(license_types_id: LicenseType.first.id)
# license = License.new(user_id: self.id, license_types_id: 1)
# license.save
# self.license.create(license_types_id: LicenseType.first.id)
end
end
models / license.rb
class License < ApplicationRecord
belongs_to :license_type
belongs_to :user
after_create :set_expired_at
private
def set_expired_at
# self.expired_at = DateTime.now + self.license_types.duration
end
end
在Rails控制台中,
2.5.1 :001 > license = License.new(license_types_id: LicenseType.first.id)
LicenseType Load (0.4ms) SELECT "license_types".* FROM "license_types" ORDER BY "license_types"."id" ASC LIMIT $1 [["LIMIT", 1]]
=> #<License id: nil, expired_at: nil, created_at: nil, updated_at: nil, license_types_id: 1, user_id: nil>
2.5.1 :002 > license.save
(0.5ms) BEGIN
(0.2ms) ROLLBACK
=> false
schema.rb ,
create_table "licenses", force: :cascade do |t|
t.datetime "expired_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.bigint "license_types_id"
t.bigint "user_id"
t.index ["license_types_id"], name: "index_licenses_on_license_types_id"
t.index ["user_id"], name: "index_licenses_on_user_id"
end
create_table "users", force: :cascade do |t|
t.string "email", default: ""
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "username"
t.string "key"
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
t.index ["username"], name: "index_users_on_username", unique: true
end
add_foreign_key "licenses", "users"
创建后如何为新用户设置许可证?
答案 0 :(得分:1)
许可模型包含两个外键user_id
和license_type_id
=>这意味着在创建License
之前必须有一个拥有此License
的用户,因为Rails 5约定说user_id
必须存在
=>而且必须存在LicenseType
,因为Rails 5约定说license_type_id
必须存在
回滚原因可以通过以下方法进行调查
license = License.new(license_types_id: LicenseType.first.id)
license.save
#Begin
#ROLLBACK
errors_stack = license.errors
errors_stack
包含导致回滚的模型级别错误
要解决这些回滚问题
user = User.first #or current_user
license = user.license.new(license_type_id: LicenseType.first.id)
license.save
或
user = User.first #or current_user
license = License.new(license_type_id: LicenseType.first.id, user_id: user.id)
license.save
或者要创建User
并为用户分配License
#after_create的替代方法:create_assocs
new_user = User.new(...)
new_user.license.build(license_type_id: LicenseType.first.id)
new_user.save
答案 1 :(得分:0)
您确定这种“没有错误”吗?在Rails 5中,默认情况下需要belongs_to
关联,所以我想这是因为它失败了(在保存尝试之前,您没有设置user
关联)。因此,您应该设置license.user
或设置:
belongs_to :user, optional: true
如果您的业务逻辑不需要在License
模型中。