ruby-on-rails - Heroku Production - 属性未保存在生产中,但在开发中有效
问题描述
App 正在使用 Gems 的组合创建一个多租户应用程序,帐户所有者可以在其中邀请用户。然后根据当前用户的 :account_id 值将显示的所有数据限定为 :account_id 列。它正在为帐户和用户使用设计。它使用 Devise Invitable 允许帐户通过电子邮件向用户发送邀请以创建他们的帐户,然后在创建时为该用户分配邀请他们加入的帐户 ID 的 :account_id。
在开发环境中, :account_id 在 InvitationsController#Create 操作时被正确分配。在 Heroku 的生产环境中,它无法通过相同的操作将 :account_id 保存给用户。
宝石文件:
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '2.7.1'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.0.3', '>= 6.0.3.2'
# Use postgresql as the database for Active Record
gem 'pg', '>= 0.18', '< 2.0'
# Use Puma as the app server
gem 'puma', '~> 4.1'
# Use SCSS for stylesheets
gem 'sass-rails', '>= 6'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 4.0'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.7'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'
# Gem for Users and Account control
gem 'devise'
# Gems for making things pretty
gem 'bootstrap'
gem 'font-awesome-rails'
# Use for creating graphs and grouping data
gem 'chartkick'
gem 'groupdate'
# Pagination gem
gem 'kaminari'
# Use Active Storage variant
# gem 'image_processing', '~> 1.2'
#Use to make mulitenancy simpler
gem 'acts_as_tenant'
#For Account owners to invite their company's Users
gem 'devise_invitable'
# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.2', require: false
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end
group :development do
# Access an interactive console on exception pages or by calling 'console' anywhere in the code.
gem 'web-console', '>= 3.3.0'
gem 'listen', '~> 3.2'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
end
group :test do
# Adds support for Capybara system testing and selenium driver
gem 'capybara', '>= 2.15'
gem 'selenium-webdriver'
# Easy installation and use of web drivers to run system tests with browsers
gem 'webdrivers'
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
路由.rb
Rails.application.routes.draw do
devise_for :accounts, controllers: { sessions: 'accounts/sessions', registrations: 'accounts/registrations', invitations: 'users/invitations' }
devise_for :users, controllers: { sessions: 'users/sessions', invitations: 'users/invitations' }
resources :downtimes
resources :downtime_criteria
resources :actionitems do
resources :comments
end
resources :production_runs do
resources :production_hours
end
root 'welcome#index'
end
应用控制器
class ApplicationController < ActionController::Base
set_current_tenant_through_filter
before_action :find_current_tenant
def find_current_tenant
current_account_id = user_signed_in? ? current_user.account : nil
set_current_tenant(current_account_id)
end
def authenticate_inviter!
authenticate_account!(force: true)
end
end
/users/InvitationsController
class Users::InvitationsController < Devise::InvitationsController
before_action :configure_permitted_parameters, if: :devise_controller?
def create
super
User.invite!(:email => params[:email], :account_id => current_account.id)
User.where(email: params[:user][:email]).update_all(account_id: current_account.id)
end
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:invite, keys: [:account_id])
end
end
账户.rb
class Account < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :users, dependent: :destroy
include DeviseInvitable::Inviter
end
用户.rb
class User < ApplicationRecord
acts_as_tenant(:account)
belongs_to :account
validates :email, :account_id, presence: true
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :invitable, :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
end
/users/invitations/_new.html.erb
<h2><%= t "devise.invitations.new.header" %></h2>
<%= form_for(resource, as: @invitation, url: invitation_path(resource_name), html: { method: :post }) do |f| %>
<%= render "users/shared/error_messages", resource: resource %>
<% resource.class.invite_key_fields.each do |field| -%>
<div class="field">
<%= f.label field %><br />
<%= f.text_field field %>
</div>
<% end -%>
<div class="actions">
<%= f.submit t("devise.invitations.new.submit_button") %>
</div>
<% end %>
heroku 日志 --tail
2020-09-03T02:57:16.793404+00:00 heroku[router]: at=info method=POST path="/users/invitation" host=gentle-cliffs-24710.herokuapp.com request_id=cdfe6b7c-7473-47d9-9ff1-ebca721ba0e8 fwd="108.166.134.134" dyno=web.1 connect=0ms service=646ms status=500 bytes=1827 protocol=https
2020-09-03T02:57:16.744528+00:00 app[web.1]: D, [2020-09-03T02:57:16.744380 #4] DEBUG -- : [cdfe6b7c-7473-47d9-9ff1-ebca721ba0e8] User Load (1.2ms) SELECT "users".* FROM "users" WHERE "users"."invitation_token" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["invitation_token", "f865f1a5e1e8e8f1576567e1f539ba6d9d3a1e85d5b21fa8e8fc72a0a7a1341d"], ["LIMIT", 1]]
2020-09-03T02:57:16.750905+00:00 app[web.1]: D, [2020-09-03T02:57:16.750774 #4] DEBUG -- : [cdfe6b7c-7473-47d9-9ff1-ebca721ba0e8] (3.2ms) BEGIN
2020-09-03T02:57:16.753036+00:00 app[web.1]: D, [2020-09-03T02:57:16.752895 #4] DEBUG -- : [cdfe6b7c-7473-47d9-9ff1-ebca721ba0e8] User Create (1.3ms) INSERT INTO "users" ("email", "encrypted_password", "created_at", "updated_at", "invitation_token", "invitation_created_at", "invitation_sent_at", "invited_by_type", "invited_by_id") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING "id" [["email", "testing12345@gmail.com"], ["encrypted_password", "$2a$11$sPBv6kzgZNZcaDhRpNORcuThcEFQQh8xqTiIJ45izWX0v3eyBtgKK"], ["created_at", "2020-09-03 02:57:16.746102"], ["updated_at", "2020-09-03 02:57:16.746102"], ["invitation_token", "f865f1a5e1e8e8f1576567e1f539ba6d9d3a1e85d5b21fa8e8fc72a0a7a1341d"], ["invitation_created_at", "2020-09-03 02:57:16.744928"], ["invitation_sent_at", "2020-09-03 02:57:16.744928"], ["invited_by_type", "Account"], ["invited_by_id", 2]]
2020-09-03T02:57:16.758183+00:00 app[web.1]: D, [2020-09-03T02:57:16.758057 #4] DEBUG -- : [cdfe6b7c-7473-47d9-9ff1-ebca721ba0e8] (4.4ms) COMMIT
2020-09-03T02:57:16.765162+00:00 app[web.1]: I, [2020-09-03T02:57:16.765033 #4] INFO -- : [cdfe6b7c-7473-47d9-9ff1-ebca721ba0e8] Rendering users/mailer/invitation_instructions.html.erb
2020-09-03T02:57:16.767966+00:00 app[web.1]: I, [2020-09-03T02:57:16.767824 #4] INFO -- : [cdfe6b7c-7473-47d9-9ff1-ebca721ba0e8] Rendered users/mailer/invitation_instructions.html.erb (Duration: 2.6ms | Allocations: 517)
2020-09-03T02:57:16.771219+00:00 app[web.1]: I, [2020-09-03T02:57:16.771101 #4] INFO -- : [cdfe6b7c-7473-47d9-9ff1-ebca721ba0e8] Rendering users/mailer/invitation_instructions.text.erb
2020-09-03T02:57:16.773629+00:00 app[web.1]: I, [2020-09-03T02:57:16.773519 #4] INFO -- : [cdfe6b7c-7473-47d9-9ff1-ebca721ba0e8] Rendered users/mailer/invitation_instructions.text.erb (Duration: 2.2ms | Allocations: 393)
2020-09-03T02:57:16.777350+00:00 app[web.1]: D, [2020-09-03T02:57:16.777199 #4] DEBUG -- : [cdfe6b7c-7473-47d9-9ff1-ebca721ba0e8] Devise::Mailer#invitation_instructions: processed outbound mail in 18.2ms
2020-09-03T02:57:16.788770+00:00 app[web.1]: I, [2020-09-03T02:57:16.788627 #4] INFO -- : [cdfe6b7c-7473-47d9-9ff1-ebca721ba0e8] Delivered mail 5f505b8cbe3f1_493944479@739a533a-af2a-474c-a8c4-7bacfd76c8ca.mail (11.2ms)
2020-09-03T02:57:16.788846+00:00 app[web.1]: D, [2020-09-03T02:57:16.788754 #4] DEBUG -- : [cdfe6b7c-7473-47d9-9ff1-ebca721ba0e8] Date: Thu, 03 Sep 2020 02:57:16 +0000
2020-09-03T02:57:16.788847+00:00 app[web.1]: From: please-change-me-at-config-initializers-devise@example.com
2020-09-03T02:57:16.788847+00:00 app[web.1]: Reply-To: please-change-me-at-config-initializers-devise@example.com
2020-09-03T02:57:16.788848+00:00 app[web.1]: To: testing12345@gmail.com
2020-09-03T02:57:16.788849+00:00 app[web.1]: Message-ID: <5f505b8cbe3f1_493944479@739a533a-af2a-474c-a8c4-7bacfd76c8ca.mail>
2020-09-03T02:57:16.788850+00:00 app[web.1]: Subject: Invitation instructions
2020-09-03T02:57:16.788850+00:00 app[web.1]: Mime-Version: 1.0
2020-09-03T02:57:16.788851+00:00 app[web.1]: Content-Type: multipart/alternative;
2020-09-03T02:57:16.788851+00:00 app[web.1]: boundary="--==_mimepart_5f505b8cbd144_493944334";
2020-09-03T02:57:16.788852+00:00 app[web.1]: charset=UTF-8
2020-09-03T02:57:16.788852+00:00 app[web.1]: Content-Transfer-Encoding: 7bit
2020-09-03T02:57:16.788853+00:00 app[web.1]:
2020-09-03T02:57:16.788853+00:00 app[web.1]:
2020-09-03T02:57:16.788853+00:00 app[web.1]: ----==_mimepart_5f505b8cbd144_493944334
2020-09-03T02:57:16.788854+00:00 app[web.1]: Content-Type: text/plain;
2020-09-03T02:57:16.788854+00:00 app[web.1]: charset=UTF-8
2020-09-03T02:57:16.788854+00:00 app[web.1]: Content-Transfer-Encoding: 7bit
2020-09-03T02:57:16.788855+00:00 app[web.1]:
2020-09-03T02:57:16.788855+00:00 app[web.1]: Hello testing12345@gmail.com
2020-09-03T02:57:16.788855+00:00 app[web.1]:
2020-09-03T02:57:16.788856+00:00 app[web.1]: Someone has invited you to https://gentle-cliffs-24710.herokuapp.com/:3000/, you can accept it through the link below.
2020-09-03T02:57:16.788856+00:00 app[web.1]:
2020-09-03T02:57:16.788857+00:00 app[web.1]: https://gentle-cliffs-24710.herokuapp.com/:3000/users/invitation/accept?invitation_token=yGi2R5_2acRXY3XJXSVN
2020-09-03T02:57:16.788857+00:00 app[web.1]:
2020-09-03T02:57:16.788857+00:00 app[web.1]:
2020-09-03T02:57:16.788858+00:00 app[web.1]: If you don't want to accept the invitation, please ignore this email. Your account won't be created until you access the link above and set your password.
2020-09-03T02:57:16.788858+00:00 app[web.1]:
2020-09-03T02:57:16.788858+00:00 app[web.1]: ----==_mimepart_5f505b8cbd144_493944334
2020-09-03T02:57:16.788859+00:00 app[web.1]: Content-Type: text/html;
2020-09-03T02:57:16.788859+00:00 app[web.1]: charset=UTF-8
2020-09-03T02:57:16.788859+00:00 app[web.1]: Content-Transfer-Encoding: 7bit
2020-09-03T02:57:16.788860+00:00 app[web.1]:
2020-09-03T02:57:16.788860+00:00 app[web.1]: <p>Hello testing12345@gmail.com</p>
2020-09-03T02:57:16.788861+00:00 app[web.1]:
2020-09-03T02:57:16.788861+00:00 app[web.1]: <p>Someone has invited you to https://gentle-cliffs-24710.herokuapp.com/:3000/, you can accept it through the link below.</p>
2020-09-03T02:57:16.788861+00:00 app[web.1]:
2020-09-03T02:57:16.788862+00:00 app[web.1]: <p><a href="https://gentle-cliffs-24710.herokuapp.com/:3000/users/invitation/accept?invitation_token=yGi2R5_2acRXY3XJXSVN">Accept invitation</a></p>
2020-09-03T02:57:16.788862+00:00 app[web.1]:
2020-09-03T02:57:16.788863+00:00 app[web.1]:
2020-09-03T02:57:16.788863+00:00 app[web.1]: <p>If you don't want to accept the invitation, please ignore this email. Your account won't be created until you access the link above and set your password.</p>
2020-09-03T02:57:16.788864+00:00 app[web.1]:
2020-09-03T02:57:16.788864+00:00 app[web.1]: ----==_mimepart_5f505b8cbd144_493944334--
2020-09-03T02:57:16.788865+00:00 app[web.1]:
2020-09-03T02:57:16.789171+00:00 app[web.1]: I, [2020-09-03T02:57:16.789103 #4] INFO -- : [cdfe6b7c-7473-47d9-9ff1-ebca721ba0e8] Completed 500 Internal Server Error in 586ms (ActiveRecord: 21.3ms | Allocations: 11597)
2020-09-03T02:57:16.790582+00:00 app[web.1]: F, [2020-09-03T02:57:16.790480 #4] FATAL -- : [cdfe6b7c-7473-47d9-9ff1-ebca721ba0e8]
2020-09-03T02:57:16.790584+00:00 app[web.1]: [cdfe6b7c-7473-47d9-9ff1-ebca721ba0e8] Errno::ECONNREFUSED (Connection refused - connect(2) for "localhost" port 25):
2020-09-03T02:57:16.790584+00:00 app[web.1]: [cdfe6b7c-7473-47d9-9ff1-ebca721ba0e8]
2020-09-03T02:57:16.790585+00:00 app[web.1]: [cdfe6b7c-7473-47d9-9ff1-ebca721ba0e8] app/controllers/users/invitations_controller.rb:5:in `create'
heroku run rails c
irb(main):006:0> User.last
D, [2020-09-03T02:58:48.541138 #4] DEBUG -- : User Load (1.2ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1 [["LIMIT", 1]]
=> #<User id: 8, email: "testing12345@gmail.com", created_at: "2020-09-03 02:57:16", updated_at: "2020-09-03 02:57:16", ***account_id: nil***>
irb(main):007:0>
我试过运行heroku重启。没有想法......有人有一些见识吗?谢谢
解决方案
推荐阅读
- javascript - 映射数组时GetBoundingClientRect不是函数
- rest - 在 Binance 中生成新的存款地址
- php - Yii2 kartik-v tabsX 过滤后返回相同的选项卡
- sql - Postgresql 插入如果不存在 ON CONFLICT IGNORE 不工作
- python - 将数组元素明智地组合以形成坐标数组
- html - 如何使用 CSS 使图像滑块重复为无限循环或选取框
- python - 通过在 Python 中跳过一个字符串来制作两列?
- c++ - MSVC 可以找到匹配的构造函数,但 gcc 和 clang 找不到
- android - 如何显示较小的视频文件比较大的视频文件流速度更快?
- unity3d - 将精灵隐藏在墙后,但当它在墙前时显示,Unity