涉及不同类型密钥的rails关联

时间:2015-02-21 00:10:04

标签: ruby-on-rails postgresql has-many

我有两个带模式的表:

create_table "posts"
end

create_table "comments" do |t|
  t.string post_id
end

我的问题是Post.includes(:comments)会导致postgres错误:

  ERROR:  operator does not exist: character varying = integer
                                                       ^
  HINT:  No operator matches the given name and argument type(s).
  You might need to add explicit type casts

这是因为Post.id是一个整数,而Comments.post_id是一个字符串,而postgres不会自动将INTEGER转换为VARCHAR。

显而易见的解决方案是使Post.id和Comment.post_id成为相同的类型,但我不想这样做,因为评论来自一个单独的gem(ActiveAdmin),我不想将我的Post.id更改为字符串。

在rails 3中,我可以使用has_many:finder_sql通过显式转换来使其工作。

在Rails 4中不推荐使用finder_sql,有什么方法可以使它工作吗?

1 个答案:

答案 0 :(得分:0)

Rails约定是使用Integer作为默认ID,所以我真的会尝试顺从。保持应用程序数据的一致性非常重要,并且可以避免很多麻烦。

为了解决这个问题,我会将Comments.post_id更改为模式中的Integer,并通过将其转换为类setter方法中的Integer来处理从Gem接收的String。

class Comment < ActiveRecord def person_id=(string) @person_id = string.to_i end end

这样您就可以在应用程序到达时立即键入String。从那时起,你所有的ID都以同样的方式嘎嘎叫,你可以照常进行。 comment = Api.get.comment("200") # <ApiComment person_id="1"> Comment.create(comment) # <Comment person_id=1>

相关问题