Rails与字符串的关联导致AssociationTypeMismatch错误

时间:2016-08-04 20:58:35

标签: ruby-on-rails activerecord associations

我的DevicePurchase模型中有以下内容 -

has_one :coupon_code, primary_key: 'coupon_code', foreign_key: 'name'

应用程序我正在通过优惠券的名称(字符串,即“SummerPromo123”)将DevicePurchase与CouponCode相关联而不是想法。我上面添加的关联看起来有效,但是当我尝试DevicePurchase.last.update(...)时,我收到了这个 -

DevicePurchase.last.update(coupon_code: 'yLVDnw')
  DevicePurchase Load (2.4ms)  SELECT "device_purchases".* FROM "device_purchases" ORDER BY "device_purchases"."id" DESC LIMIT 1
  (0.2ms)  BEGIN
  (0.3ms)  ROLLBACK
ActiveRecord::AssociationTypeMismatch: CouponCode(#70224191762780) expected, got String(#70224129222500)
  from /Users/ryangrush/.rvm/gems/ruby-2.2.4@myautobrain/gems/activerecord-4.0.12/lib/active_record/associations/association.rb:224:in `raise_on_type_mismatch!'
  from /Users/ryangrush/.rvm/gems/ruby-2.2.4@myautobrain/gems/activerecord-4.0.12/lib/active_record/associations/has_one_association.rb:25:in `replace'
  from /Users/ryangrush/.rvm/gems/ruby-2.2.4@myautobrain/gems/activerecord-4.0.12/lib/active_record/associations/singular_association.rb:17:in `writer'
  from /Users/ryangrush/.rvm/gems/ruby-2.2.4@myautobrain/gems/activerecord-4.0.12/lib/active_record/associations/builder/association.rb:78:in `coupon_code='
  from /Users/ryangrush/.rvm/gems/ruby-2.2.4@myautobrain/gems/activerecord-4.0.12/lib/active_record/attribute_assignment.rb:42:in `public_send'
  from /Users/ryangrush/.rvm/gems/ruby-2.2.4@myautobrain/gems/activerecord-4.0.12/lib/active_record/attribute_assignment.rb:42:in `_assign_attribute'
  from /Users/ryangrush/.rvm/gems/ruby-2.2.4@myautobrain/gems/activerecord-4.0.12/lib/active_record/attribute_assignment.rb:29:in `block in assign_attributes'
  from /Users/ryangrush/.rvm/gems/ruby-2.2.4@myautobrain/gems/activerecord-4.0.12/lib/active_record/attribute_assignment.rb:23:in `each'
  from /Users/ryangrush/.rvm/gems/ruby-2.2.4@myautobrain/gems/activerecord-4.0.12/lib/active_record/attribute_assignment.rb:23:in `assign_attributes'
  from /Users/ryangrush/.rvm/gems/ruby-2.2.4@myautobrain/gems/activerecord-4.0.12/lib/active_record/persistence.rb:230:in `block in update'
  from /Users/ryangrush/.rvm/gems/ruby-2.2.4@myautobrain/gems/activerecord-4.0.12/lib/active_record/transactions.rb:330:in `block in with_transaction_returning_status'
  from /Users/ryangrush/.rvm/gems/ruby-2.2.4@myautobrain/gems/activerecord-4.0.12/lib/active_record/connection_adapters/abstract/database_statements.rb:203:in `block in transaction'
  from /Users/ryangrush/.rvm/gems/ruby-2.2.4@myautobrain/gems/activerecord-4.0.12/lib/active_record/connection_adapters/abstract/database_statements.rb:211:in `within_new_transaction'
  from /Users/ryangrush/.rvm/gems/ruby-2.2.4@myautobrain/gems/activerecord-4.0.12/lib/active_record/connection_adapters/abstract/database_statements.rb:203:in `transaction'
  from /Users/ryangrush/.rvm/gems/ruby-2.2.4@myautobrain/gems/activerecord-4.0.12/lib/active_record/transactions.rb:209:in `transaction'
  from /Users/ryangrush/.rvm/gems/ruby-2.2.4@myautobrain/gems/activerecord-4.0.12/lib/active_record/transactions.rb:327:in `with_transaction_returning_status'
  from /Users/ryangrush/.rvm/gems/ruby-2.2.4@myautobrain/gems/activerecord-4.0.12/lib/active_record/persistence.rb:229:in `update'
  from (irb):55
  from /Users/ryangrush/.rvm/gems/ruby-2.2.4@myautobrain/gems/railties-4.0.12/lib/rails/commands/console.rb:90:in `start'
  from /Users/ryangrush/.rvm/gems/ruby-2.2.4@myautobrain/gems/railties-4.0.12/lib/rails/commands/console.rb:9:in `start'
  from /Users/ryangrush/.rvm/gems/ruby-2.2.4@myautobrain/gems/railties-4.0.12/lib/rails/commands.rb:62:in `<top (required)>'
  from bin/rails:4:in `require'
  from bin/rails:4:in `<main>'2.2.4 :056 >

我找到了一些StackOverflow的答案,但我认为问题在于我的关联。

**更新**

如果我运行DevicePurchase.last.update(coupon_code: CouponCode.last),我会收到以下错误 -

SELECT 1 AS one FROM "coupon_codes" WHERE ("coupon_codes"."name" = 1188 AND "coupon_codes"."id" != 1188) LIMIT 1
PG::UndefinedFunction: ERROR:  operator does not exist: text = integer
LINE 1: ...FROM "coupon_codes"  WHERE ("coupon_codes"."name" = 1188 AND...
                                                             ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.
: SELECT  1 AS one FROM "coupon_codes"  WHERE ("coupon_codes"."name" = 1188 AND "coupon_codes"."id" != 1188) LIMIT 1
   (0.2ms)  ROLLBACK
ActiveRecord::StatementInvalid: PG::UndefinedFunction: ERROR:  operator does not exist: text = integer
LINE 1: ...FROM "coupon_codes"  WHERE ("coupon_codes"."name" = 1188 AND...
                                                             ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.

1 个答案:

答案 0 :(得分:0)

好的问题是,您的关联名称和列名相同。所以,当你尝试DevicePurchase.last.update(coupon_code: 'yLVDnw')时,Rails认为你将传递一个CouponCode对象,而不是&#34;字符串&#34;你现在拥有的价值。这就是你得到错误的原因。但如果你重命名下面的关联,你应该没问题:

has_one :coupon,
  primary_key: 'coupon_code',
  foreign_key: 'name',
  class_name: 'CouponCode'