我一直在尝试为我的用户模型构建一个工厂,当我尝试手动将值放入工厂定义中时,我似乎无法通过ActiveRecord :: AssociationTypeMismatch SubscriptionPlan。我不知道如何将subscription_plan传递给用户对象。如何使用factory_bot创建用户并附加订阅计划以获取传递规范?我写的代码如下,包括错误信息。
控制台错误
require 'rails_helper'
RSpec.describe User, type: :model do
it "should be able to create a user with factory bot" do
user = FactoryBot.create(:user, first_name: 'Daniel', subscription_plan: "Silver Plan")
expect(user.first_name).to eq('Daniel')
end
end
user_spec.rb
FactoryBot.define do
sequence :email do |n|
"person#{n}@example.com"
end
end
FactoryBot.define do
factory :user, :class => 'User' do
email
username "david101"
first_name "David"
last_name "Jones"
state "New York"
password "Golden20305@!"
password_confirmation "Golden20305@!"
subscription_plan
end
end
users.rb(RSpec)
class User < ApplicationRecord
enum role: [:user, :silver, :gold]
second_level_cache expires_in: 1.week
# Include default devise modules.
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:confirmable
include DeviseTokenAuth::Concerns::User
before_create :build_user_profile
geocoded_by :last_sign_in_ip, :latitude => :lat, :longitude => :lon
geocoded_by :user_address, :latitude => :lat, :longitude => :lon
after_validation :geocode
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
friendly_id :username, use: :slugged
belongs_to :subscription_plan
accepts_nested_attributes_for :user_profile, update_only: true
acts_as_messageable
# Validations
validates_associated :subscription_plan
validates :email, presence: true, uniqueness: true, email: {strict_mode: true}
validates :username, presence: true, length: {maximum: 15, minimum: 2},
format: {with: /\A[a-zA-Z0-9]+\Z/}, uniqueness: true
validates :first_name, presence: true, uniqueness: false, length: {maximum: 50}, format: {with: /\A[a-zA-Z]+(?: [a-zA-Z]+)?\z/}
validates :last_name, presence: true, uniqueness: false, length: {maximum: 50}, format: {with: /\A[a-zA-Z]+(?: [a-zA-Z]+)?\z/}
validates :country, presence: true
validates :state, presence: true
validates :street, presence: true
validates :city_or_town, presence: true, length: {maximum: 60, minimum: 2}
validates :zip_code, presence: true, length: {maximum: 50}, format: {with: /\A[a-z0-9\s]+\Z/i}
validates :password, password_strength: {use_dictionary: true}
def set_default_role
self.role ||= :silver
end
def set_default_plan
self.subscription_plan ||= Plan.last
end
def stripe_membership_checker
case
when self.subscription_plan_id.nil?
"Normal User"
when self.subscription_plan_id == 5
"Gold"
when self.subscription_plan_id == 4
"Silver"
else
""
end
end
protected
def confirmation_required?
false
end
end
user.rb
class SubscriptionPlan < ApplicationRecord
include Payola::Plan
has_many :users
scope :user_plan, -> {where(stripe_id: %w(silver gold))}
def redirect_path(subscription)
'/'
end
end
subscription_plan.rb
<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), :html => {:role => 'form',
:class => 'payola-onestep-subscription-form',
'data-payola-base-path' => payola_path,
'data-payola-plan-type' => resource.subscription_plan.class, 'data-payola-plan-id' => resource.subscription_plan}) do |f| %>
<div class="form-group">
<div class="col-5">
<%= f.error_notification %>
<%= devise_error_messages! %>
<span class="payola-payment-error"></span>
</div>
</div>
<div class="form-group">
<label class="col-5 col-form-label">Monthly Subscription Plan</label>
<div class="col-4">
<%= f.association :subscription_plan, collection: SubscriptionPlan.user_plan.map {|c| [c.name, c.id]}, label: false, prompt: 'Choose a plan' %>
</div>
</div>
<div class="form-group">
<label for="fg-1" class="col-4 col-form-label">Email</label>
<div class="col-4">
<%= f.input :email, label: false, required: true, autofocus: true, id: 'fg-1', placeholder: 'What is your email address?' %>
</div>
</div>
new.html.erb(新用户)
{{1}}
答案 0 :(得分:0)
不要伤害自己。
user = FactoryBot.create(:user, first_name: 'Daniel', subscription_plan: "Silver Plan")
我不知道你的subscription_plans.rb工厂是什么样的,但是你需要传递一个SubscriptionPlan ActiveRecord对象而不是"Silver Plan"
。
我通过查看此错误ActiveRecord::AssociationTypeMismatch: SubscriptionPlan(#75441564) expected, got "Silver Plan" which is an instance of String(#36231624)
这表明没有正确设置。