ruby-on-rails - Rails 5 after_create 回调创建 has_many :通过连接表
问题描述
我有Account
和我的模型Page
有has_many :through
关联的Campaigns
模型。我要做的是在使用create_after
回调创建新页面时创建连接表。
我也和模特有has_many :through
联系。Account
User
我得到的当前错误是Account must exist
. 我想要做的是抓住account_id
用户logged_in
,但很难过。
我在下面包含了我的所有模型,因此您可以了解正在发生的事情。用户创建一个帐户,获取激活电子邮件,然后登录。此时,创建的所有内容都附加到该帐户,而不是用户 - 在这种情况下,我想创建一个页面并让它通过该帐户创建一个连接表活动。
帐号.rb
class Account < ActiveRecord::Base
after_create :set_membership
belongs_to :owner, class_name: 'User'
accepts_nested_attributes_for :owner
has_many :memberships
has_many :users, through: :memberships
has_many :campaigns
has_many :pages, through: :campaigns
# Create Membership
def set_membership
user_id = self.owner_id
Membership.create!(user_id: user_id, account_id: id)
end
end
用户.rb
class User < ApplicationRecord
has_many :memberships
has_many :accounts, through: :memberships
#accepts_nested_attributes_for :accounts
attr_accessor :remember_token, :activation_token, :reset_token
before_save :downcase_email
before_create :create_activation_digest
before_save {self.email = email.downcase}
validates :name, presence: true, length: {maximum: 50}
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}, allow_nil: true
validates :password, presence: true, length: {minimum: 6}
after_create :send_activation_email
# Non-Admin User Roles
enum role: [:standard]
after_initialize :set_default_role, if: :new_record?
def set_default_role
self.role ||= :standard
end
# 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?(attribute, token)
digest = send("#{attribute}_digest")
return false if digest.nil?
BCrypt::Password.new(digest).is_password?(token)
end
# Forgets a user.
def forget
update_attribute(:remember_digest, nil)
end
# Activates an account.
def activate
# update_columns(activated: FILL_IN, activated_at: FILL_IN)
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)
# update_columns(reset_digest: FILL_IN, reset_sent_at: FILL_IN)
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
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
页面.rb
class Page < ApplicationRecord
after_create :set_campaign
belongs_to :account
has_many :campaigns
has_many :accounts, through: :campaigns
# Create Campaign
def set_campaign
Campaign.create!(account_id: account_id, page_id: id)
end
end
活动.rb
class Campaign < ApplicationRecord
belongs_to :account
belongs_to :page
end
解决方案
在 railsafter_create
回调不会关闭默认数据库策略中的事务。因此,当您调用after_create
它时,实际上数据库中没有记录。你的情况你应该尝试:
after_commit :set_membership, on: :create
或者提供记录而不是 id:
def set_membership
Membership.create!(user_id: owner_id, account: self)
end
推荐阅读
- python - LIKE 子句。在 python 连接器中 mysql
- php - 创建一个抽象类并通过其他类继承
- angular - 如何在服务构造函数中提供数据?
- javascript - 将任意回调函数附加到 dom 元素的最佳方法?
- .net-core - 将 Razor 页面拆分为子项目以使其模块化
- clojure - 在命名空间中找出 `:require` 的名称
- oracle - oracle apex 更新语句(使用选择列表和 text_field 的返回值)
- php - 如何检查重复但不刷新页面?PHP
- java - 构建 javaFX 工件 java.lang.ClassNotFoundException
- android - 默认情况下打开片段时,FAB 不可见