【问题标题】:Error self.user.update_attribute undefined method nil:Class错误 self.user.update_attribute 未定义方法 nil:Class
【发布时间】:2013-12-10 10:00:04
【问题描述】:

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

我修改了 factory.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'

我希望你能帮助我。谢谢

【问题讨论】:

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


    【解决方案1】:

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

    如果您希望此订阅始终存在于您的数据库中,请使用 db:seed rake 任务来预填充您的数据库。 (尝试谷歌搜索以了解如何执行此操作)

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

    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     
    

    【讨论】:

    • 好的,我试试你的第二个选择,我理解我的问题,但现在我的测试中有另一个问题:1) UserAction 用户登录权限失败/错误: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' # ./spec/features/user_connection_spec.rb:39:in block (2 levels) in ' I Upload my order.rb
    • 每次你看到错误'foo' undefined for nil:NilClass 这意味着你在你没有预料到的地方得到了 nil。在这种情况下,在您的 init_value 方法的第一行中,self.subscription 为 nil,因为它不是由您的工厂创建的。
    • 好的,所以我需要在我的用户工厂中添加订阅?像这样:订阅“测试”?或者不,我需要创建新工厂吗?因为订阅用于创建订单,订单用于用户。
    • 您应该在此处阅读有关工厂的信息:github.com/thoughtbot/factory_girl/blob/master/…。关于创建关联对象有一个非常好的章节。
    • 我编辑了我的帖子,但我的 update_attribute 中有错误,我不知道为什么。你能帮忙吗?
    【解决方案2】:

    create_order 尝试使用这个:

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

    使用对象而不是普通的 id。

    关于before_* 方法

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

    【讨论】:

    • 我试试你写的,我有另一个错误:ActiveModel::MassAssignmentSecurity::Error: Can't mass-assign protected attributes: user, subscription # ./app/models/user.rb :21:in `create_order'
    • 确保usersubscription 字段在Order 模型中可用。例如。验证在Order 中设置了belongs_to :userbelongs_to :subscription
    • 我的订单模型中有belongs_to :subscription 和belongs_to :user 、belongs_to :user belongs_to :subscription。如果你愿意,我可以上传我的 Order 模型。
    • 我已经更新了答案。可能是方法中缺少 return true 的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多