嵌套属性不创建Rails 4 - 多Tennant应用程序

时间:2016-10-19 02:35:12

标签: ruby-on-rails ruby-on-rails-4

所以我正在构建一个应用程序(Rails 4)并实现订阅计划,工作流程如下:

创建一个帐户,创建帐户时,使用它创建所有者,并且还应该使用它创建计划。

这是创建帐户时的服务器输出:

  SQL (0.5ms)  INSERT INTO "users" ("email", "encrypted_password", "confirmation_token", "confirmation_sent_at", "f_name", "l_name", "date_of_birth", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING "id"  [["email", "swilson@patrolvault.net"], ["encrypted_password", "$2a$11$ZFMl7BhZc3a.DnoyfiEuYO7bXqLeZ9smhhg4J.JaK00APGFdpVsgG"], ["confirmation_token", "LmdZXcuL7GJYP6nqWKvm"], ["confirmation_sent_at", 2016-10-19 02:19:21 UTC], ["f_name", "Some"], ["l_name", "Owner"], ["date_of_birth", Mon, 01 Jan 1900], ["created_at", 2016-10-19 02:19:21 UTC], ["updated_at", 2016-10-19 02:19:21 UTC]]
  SQL (0.2ms)  INSERT INTO "public"."accounts" ("subdomain", "owner_id", "created_at", "updated_at", "image_data") VALUES ($1, $2, $3, $4, $5) RETURNING "id"  [["subdomain", "testdomain1"], ["owner_id", 1], ["created_at", 2016-10-19 02:19:21 UTC], ["updated_at", 2016-10-19 02:19:21 UTC], ["image_data", "{\"id\":\"536fe1bc4a8a95d64d81dd2e4f4e10af.png\",\"storage\":\"cache\",\"metadata\":{\"filename\":\"Pvaulticon.png\",\"size\":9419,\"mime_type\":\"image/png\"}}"]]
  SQL (0.3ms)  INSERT INTO "plans" ("account_id", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["account_id", 1], ["created_at", 2016-10-19 02:19:21 UTC], ["updated_at", 2016-10-19 02:19:21 UTC]]
   (0.4ms)  COMMIT
   (0.1ms)  BEGIN
  SQL (0.4ms)  UPDATE "public"."accounts" SET "updated_at" = $1, "image_data" = $2 WHERE "public"."accounts"."id" = $3  [["updated_at", 2016-10-19 02:19:21 UTC], ["image_data", "{\"id\":\"299bf4eba233a14d65e94ea9d85893f6.png\",\"storage\":\"store\",\"metadata\":{\"filename\":\"Pvaulticon.png\",\"size\":9419,\"mime_type\":\"image/png\"}}"], ["id", 1]]
   (6.3ms)  COMMIT

但是,当我尝试在Rails控制台中查询计划时,它会返回:

2.3.1 :004 > Plan.all
  Plan Load (0.2ms)  SELECT "plans".* FROM "plans"
 => #<ActiveRecord::Relation []>

2.3.1 :007 > a.plan.plan_type
  Plan Load (0.1ms)  SELECT  "plans".* FROM "plans" WHERE "plans"."account_id" = $1 LIMIT $2  [["account_id", 1], ["LIMIT", 1]]
NoMethodError: undefined method `plan_type' for nil:NilClass
    from (irb):7
    from /Users/developer/.rvm/gems/ruby-2.3.1/gems/railties-5.0.0.1/lib/rails/commands/console.rb:65:in `start'
    from /Users/developer/.rvm/gems/ruby-2.3.1/gems/railties-5.0.0.1/lib/rails/commands/console_helper.rb:9:in `start'
    from /Users/developer/.rvm/gems/ruby-2.3.1/gems/railties-5.0.0.1/lib/rails/commands/commands_tasks.rb:78:in `console'
    from /Users/developer/.rvm/gems/ruby-2.3.1/gems/railties-5.0.0.1/lib/rails/commands/commands_tasks.rb:49:in `run_command!'
    from /Users/developer/.rvm/gems/ruby-2.3.1/gems/railties-5.0.0.1/lib/rails/commands.rb:18:in `<top (required)>'
    from /Users/developer/.rvm/gems/ruby-2.3.1/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in `require'
    from /Users/developer/.rvm/gems/ruby-2.3.1/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in `block in require'
    from /Users/developer/.rvm/gems/ruby-2.3.1/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:259:in `load_dependency'
    from /Users/developer/.rvm/gems/ruby-2.3.1/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in `require'
    from /Users/developer/Desktop/PatrolVault-Saas/PV_SAAS/bin/rails:9:in `<top (required)>'
    from /Users/developer/.rvm/gems/ruby-2.3.1/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:287:in `load'
    from /Users/developer/.rvm/gems/ruby-2.3.1/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:287:in `block in load'
    from /Users/developer/.rvm/gems/ruby-2.3.1/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:259:in `load_dependency'
    from /Users/developer/.rvm/gems/ruby-2.3.1/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:287:in `load'
    from /Users/developer/.rvm/gems/ruby-2.3.1/gems/spring-2.0.0/lib/spring/commands/rails.rb:6:in `call'
    from /Users/developer/.rvm/gems/ruby-2.3.1/gems/spring-2.0.0/lib/spring/command_wrapper.rb:38:in `call'
    from /Users/developer/.rvm/gems/ruby-2.3.1/gems/spring-2.0.0/lib/spring/application.rb:191:in `block in serve'
    from /Users/developer/.rvm/gems/ruby-2.3.1/gems/spring-2.0.0/lib/spring/application.rb:161:in `fork'
    from /Users/developer/.rvm/gems/ruby-2.3.1/gems/spring-2.0.0/lib/spring/application.rb:161:in `serve'
    from /Users/developer/.rvm/gems/ruby-2.3.1/gems/spring-2.0.0/lib/spring/application.rb:131:in `block in run'
    from /Users/developer/.rvm/gems/ruby-2.3.1/gems/spring-2.0.0/lib/spring/application.rb:125:in `loop'
    from /Users/developer/.rvm/gems/ruby-2.3.1/gems/spring-2.0.0/lib/spring/application.rb:125:in `run'
    from /Users/developer/.rvm/gems/ruby-2.3.1/gems/spring-2.0.0/lib/spring/application/boot.rb:19:in `<top (required)>'
    from /Users/developer/.rvm/rubies/ruby-2.3.1/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
    from /Users/developer/.rvm/rubies/ruby-2.3.1/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
    from -e:1:in `<main>'

以下是我的帐户模型:

class Account < ApplicationRecord
  include ImageUploader[:image]
  # Constants
  RESTRICTED_SUBDOMAINS = %w(www patrolvault admin test type taurenapplabs taurenmaterialservices)

  # Before Actions
  before_validation :downcase_subdomain

  # Relationships
  belongs_to :owner, class_name: 'User', optional: true
  accepts_nested_attributes_for :owner
  has_many :users

  # Validations
  validates :owner, presence: true

  validates :subdomain, presence: true,
                        uniqueness: { case_sensitive: false },
                        format: { with: /\A[\w\-]+\Z/i, message: 'Contains invalid characters.' },
                        exclusion: { in: RESTRICTED_SUBDOMAINS, message: 'Restricted domain name'}

  has_one :plan
  accepts_nested_attributes_for :plan

  private

  def downcase_subdomain
    self.subdomain = self.subdomain.downcase
  end

end

这是我的计划模型:

class Plan < ApplicationRecord
  # Enum & Constants
  enum plan_type: [:responder, :first_responder, :patrol_pro, :guardian]

  USER_LIMITS = ActiveSupport::HashWithIndifferentAccess.new(
    responder:        6,
    first_responder:  12,
    patrol_pro:       30,
    guardian:         60
  )

  # Before Actions

  # Relationships
  belongs_to :account, optional: true

end

以下是帐户管理员:

class AccountsController < ApplicationController
  skip_before_action :authenticate_user!, only: [:new, :create]

  def new
    @account = Account.new
    @account.build_owner
    @account.build_plan
  end

  def create
    @account = Account.new(account_params)
    respond_to do |format|
      if @account.valid?
        Apartment::Tenant.create(@account.subdomain)
        Apartment::Tenant.switch!(@account.subdomain)
        @account.save
        format.html {redirect_to new_user_session_url(subdomain: @account.subdomain)}
      else
        format.html {render :new}
      end
    end
  end

  private

  def account_params
    params.require(:account).permit(:subdomain, :image, plan_attributes: [:plan_type, :id], owner_attributes: [:email, :password, :password_confirmation, :f_name, :l_name, :date_of_birth])
  end

  def set_account
    @account = Account.find(params[:id])
  end

end

和计划控制器:

class PlansController < ApplicationController

  private

  def plan_params
    params.require(:plan).permit(:account_id, :plan_type)
  end

end

1 个答案:

答案 0 :(得分:1)

您的计划是否在帐户租户之外创建?我看到您在创建帐户后切换租户,因此可能会创建记录,但之后它不可见,因为它位于全球租户中

您可能需要计划成为一个全球模型,例如住在租户之外的帐户。