Вложенный атрибут, не создающий Rails 4 — Многопользовательское приложение

#ruby-on-rails #ruby-on-rails-4

#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 amp; 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:

Создается ли ваш план за пределами клиента учетной записи? Я вижу, что вы переключаете арендаторов после создания учетной записи, поэтому, возможно, это создает запись, но тогда она не видна, потому что она находится в глобальном клиенте

Возможно, вам потребуется, чтобы Plan был глобальной моделью, подобной учетной записи, которая находится за пределами клиентов.