Откат рельсов при сохранении модели - PullRequest
0 голосов
/ 28 января 2019

Я создаю сервер лицензий, но я застрял с проблемой, что Rails не может сохранить модель.

Я установил after_create метод в User модели, но мне не повезло, также япопытался создать License модель с консолью Rails, но она откатила транзакцию и не показала никакой ошибки.

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

в консоли рельсов,

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"

Что я должен сделать, чтобы установить лицензию для нового пользователя после создания?

Ответы [ 2 ]

0 голосов
/ 28 января 2019

Модель лицензии содержит два внешних ключа 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 и назначитьпользователь a License # Альтернатива after_create: create_assocs

new_user = User.new(...)
new_user.license.build(license_type_id: LicenseType.first.id)
new_user.save
0 голосов
/ 28 января 2019

Вы уверены в этом "без ошибок"?В Rails 5 ассоциация belongs_to требуется по умолчанию, поэтому я думаю, это потому, что она не срабатывает (вы не устанавливаете ассоциацию user до попытки сохранения).Так что либо вы должны установить license.user, либо установить:

belongs_to :user, optional: true

в модели License, если ваша бизнес-логика не требует этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...