错误self.user.update_attribute undefined方法nil:Class

时间:2013-12-10 10:00:05

标签: ruby-on-rails ruby ruby-on-rails-3 rspec capybara

更新帖子我是RoR中的菜鸟,我开始测试。我有一个应用程序,我尝试使用rspec和capybara测试,我想创建用户并测试登录。但是,当我进行测试时,我的模型用户有一些错误,因为在我的应用程序中我创建用户并调用after_create:create_order

我修改了我的factories.rb,但我的update_attributes

中有错误

查看我的模型user.rb

    class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :confirmable,
  # :lockable, :timeoutable and :omniauthable
  has_many :ratings
  has_many :rated_sounds, :through => :ratings, :source => :sounds
  has_many :sounds ,:dependent => :destroy
  has_many :orders ,:dependent => :destroy
  has_many :song_ups ,:dependent => :destroy
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable,
         :registerable, :confirmable
  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :password, :password_confirmation, :remember_me,
                  :nom, :prenom, :societe, :tel, :cgu, :sign_in_count, :trans_simu,
            :trans_limit, :project, :vat_number, :adress, :zip_code, :city, :tutorial

  after_create :create_order

 def create_order
  order = Order.create(user_id: self.id,files_left: 3)
  order.subscription =  Subscription.where(category: 'test').first || Subscription.create(category: 'test')
  self.update_attribute(:trans_limit, 1)

  #Ancien Order
 # Order.create(user_id: self.id, subscription_id: Subscription.where(category: 'test').first.id, files_left: 3)
  # self.update_attribute(:trans_limit, 1)
end

  def test?
    self.orders.trial.present? && self.orders.count==1
  end

  def unlimited?
    !self.test? && self.orders.current.where(time_left: -1).any?
  end

  def allow_send?
    !self.finish_order? && self.sounds.in_progress.count < self.trans_limit.to_i
  end

  def finish_order?
    self.orders.current.empty?
  end
end

为了在我的测试中创建我的用户,我使用FactoryGirl。我写这个:

require 'factory_girl'

     FactoryGirl.define  do
          factory :user do
             sequence(:email) {|n| "email#{n}@factory.com" }
             password "foobar"
             password_confirmation "foobar"
             societe "RspecTest"
             prenom "John"
             nom "Doe"
             tel "0101010101"
             confirmed_at Time.now
             association :order
          end
          factory :order do
            association :subscription

          end
          factory :subscription do
          end
        end

我的一个测试是:

scenario "User login right" do
    visit new_user_session_path
    current_path.should == "/users/sign_in"
    page.html.should include('<h2>Se connecter</h2>')
    user = FactoryGirl.create(:user)
    fill_in "Email", :with => user.email
    fill_in "Mot de passe", :with => user.password
    check "user_remember_me"
    click_button "Connexion"
    page.should have_content('Mon compte')
    current_path.should == root_path
  end

我的订单.rb

class Order < ActiveRecord::Base
  attr_accessible :nb_files, :user_id, :period, :time_left, :subscription_id, :promo_id, :promo_end_date, :max_time_file, :files_left, :ended_at
  belongs_to :user
  belongs_to :subscription
  scope :current, where('files_left != ? AND time_left != ? AND (ended_at >= ? OR ended_at IS ?)', 0, 0, Time.now, nil)
  before_create :init_value

  def self.trial
    self.where(subscription_id: Subscription.where(category: 'test').first.id).first
  end

  def init_value
    self.time_left = self.subscription.trans_seconds
    self.max_time_file = self.subscription.max_time_file
    if self.subscription.category != 'test'
        self.user.update_attribute(:trans_limit, 1)
      Order.where(user_id: self.user_id, subscription_id: Subscription.where(category: 'test')).destroy_all
    else
      self.files_left = 3
    end
  end
end

我的错误:

Failure/Error: user = FactoryGirl.create(:user)
NoMethodError:
undefined method `trans_seconds' for nil:NilClass
# ./app/models/order.rb:13:in `init_value'
# ./app/models/user.rb:21:in `create_order'

我希望你能帮助我。感谢的

2 个答案:

答案 0 :(得分:1)

create_order尝试使用此功能:

Order.create!(user: self, subscription: Subscription.where(category: 'test').first, files_left: 3)

使用对象而不是普通ID。

开启before_*方法

要确保验证通过,请在这些方法的最后返回true。在您的情况下,请在return true方法的末尾添加init_value

答案 1 :(得分:1)

您的数据库中没有包含“test”类别的订阅。解决方案取决于您希望如何处理此类错误。

如果您希望此订阅始终位于数据库中,请使用db:seed rake task预填充数据库。 (尝试使用Google搜索以了解如何执行此操作)

如果您不想分配任何订阅(如果不存在),请尝试:

def create_order
  order = Order.create(user_id: self.id,files_left: 3)
  order.subscription =  Subscription.where(category: 'test').first
  self.update_attribute(:trans_limit, 1)
end

最后,如果你想创建这样的订阅,如果它不存在:

def create_order
  order = Order.create(user_id: self.id,files_left: 3)
  order.subscription =  Subscription.find_or_create_by_category('test')
  self.update_attribute(:trans_limit, 1)
end