尝试使用实例化对象调用函数时没有方法错误

时间:2012-01-27 22:20:13

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-3.1

我有一个包含三个字段 user_id,product_id unique_token 的模型令牌。在控制器中,我用 @token 对象从表单中收集> user_id 和 product_id值。然后我用该对象调用save_with_payment函数,在函数中我想生成随机字符串3次并保存在 unique_token字段中。问题是self.tokens.create!( unique_token: Digest::SHA1.hexdigest("random string") )没有给我任何方法错误undefined method tokens。我在这里做错了什么?为了澄清我想要完成的事情,我希望能够检索生成的unique_tokens列表与 user_id product_id 相关联,例如User.find(1).tokensProduct.find(1).tokens。模型关联为User has_many Tokens Product has_many Tokens注意:unique_token字段最初来自Token模型,user_id和product_id只是ref主键。非常感谢!

def create
  @token=Token.new(params[:token])
  if @token.save_with_payment
    redirect_to :controller => "products", :action => "index"
  else
    redirect_to :action => "new"
  end
end

class Token < ActiveRecord::Base
  require 'digest/sha1'

  def save_with_payment
 #  if valid?
 #   customer = Stripe::Charge.create(amount:buck,:currency => "usd",card:stripe_card_token,:description => "Charge for bucks")
#self.stripe_customer_token = customer.id
    3.times do
      self.tokens.create!(unique_token: Digest::SHA1.hexdigest("random string"))
    end 
    save!
  end
end

1 个答案:

答案 0 :(得分:2)

令牌类上没有令牌方法。由于您要创建三个令牌,因此不需要@token实例。只需将save_with_payment设为类方法:

def create
  if Token.save_with_payment(params[:token])
    redirect_to :controller => "products", :action => "index"
  else
    redirect_to :action => "new"
  end
end

class Token < ActiveRecord::Base
  require 'digest/sha1'

  def self.save_with_payment(attributes)
    attributes.merge!(unique_token: Digest::SHA1.hexdigest("foo"))
    3.times do
      self.create!(attributes)
    end
  end

end

希望这有帮助。

您可能也希望将循环包装在开始/救援中。否则如果2或3创建!你最终没有使用令牌并重定向到“新”。

对第1条评论的回应: 如果使用类方法,那将无效。你不能打电话有效吗?因为你不在Token实例的上下文中。我不建议坚持使用实例方法。如果您确实将其更改为类方法,则需要将其包装在事务块中:

def self.save_with_payment(attributes)
  transaction do
    attributes.merge!(unique_token: Digest::SHA1.hexdigest("foo"))
    3.times do
      self.create!(attributes)
    end
  rescue
    false
  end
end

如果有任何创建,那应该回滚SQL事务!调用失败并将false返回给控制器创建操作。

我将客户代码从令牌中取出(令牌不应该关心创建/检索客户)并将其置于控制器操作中。将相关信息传递给save_with_payments。像:

self.save_with_payments(customer, attributes)
  ...
end