我可以使用现有数据在轨道模型上创建两个现有ruby之间的关系吗?

时间:2014-05-18 11:59:14

标签: sql ruby-on-rails relationship jointable

我在实时应用程序中有两个现有数据模型,目前彼此之间没有任何关系。它们主要用于存储和快速查找,但现在我们看到需要加入它们:

# == Schema Information
#
# Table name: subscriptions
#
#  id                :integer          not null, primary key
#  app_id            :string(255)
#  user_id           :string(255)
#  effective_date    :datetime
#  expiration_date   :datetime
#  last_validated    :datetime
#  created_at        :datetime         not null
#  updated_at        :datetime         not null
#  active            :boolean
#  subscription_type :string(255)
#

class Subscription < ActiveRecord::Base
end

# == Schema Information
#
# Table name: apns_tokens
#
#  id         :integer          not null, primary key
#  app_id     :string(255)
#  user_id    :string(255)
#  apns_token :text
#  created_at :datetime         not null
#  updated_at :datetime         not null
#

class ApnsTokens < ActiveRecord::Base
end

我需要从apns_tokens模型中找到属于同一user_id的所有apns_token。我希望能够查询类似的内容:

subscription = Subscription.where("app_id = ? AND user_id = ?", params[:app_id], params[:user_id]).last
token = subscription.apns_token.apns_token

订阅和apns_tokens模型中的user_id都是唯一的。

1)是否可以创建一个has_one belongs_to关系,以及如何在apns_tokens模型中填充新的外键'subscription_id'?

2)这里有什么快速解决方法,如何在rails中编写一个sql语句来加入user_id?

编辑:快速修复有效,但在一个查询中必须有更好的方法吗?

subscribed_users = Subscription.where("active = ? and app_id = ?", true, app.app_id).collect { |u| u.user_id }
apns_tokens = ApnsTokens.where(user_id: subscribed_users).collect { |t| t.apns_token }

谢谢!

1 个答案:

答案 0 :(得分:0)

如果我理解了这个问题,你有两个共享一个值的模型(在这种情况下是user_id),你想在它们之间创建一个关系。

也许您可以使用has_one关系中的primary_key和foreign_key参数,这样您就可以使用除idrelationship_id之外的其他列:http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_one

遵循API文档,您可以编写

class Subscription

  has_one :apns_token, primary_key: :user_id, foreign_key: :user_id

end

class ApnsToken

  has_one :subscription, primary_key: :user_id, foreign_key: :user_id

end

我想到的另一个解决方案是使用中间关系。

由于您有user_id列,我猜您在Subscription和ApnsToken类中有belongs_to个关系。

如果您在User类中有has one个关系,则可以使用through关系中的has_one param来表示您通过用户关系订阅了apns_token。

class User

  has_one :apns_token
  has_one :subscription

end

class Subscription

  belongs_to :user
  has_one :apns_token, through: :user

end

class ApnsToken

  belongs_to :user
  has_one :subscription, through: :user

end

我还没有为此示例测试此代码,但这两种解决方案都可以正常工作:)