简体   繁体   English

Rails has_many STI和sub STI

[英]Rails has_many STI with sub STI

I think it is more of a "Model Design" issue than a rails issue. 我认为与其说是Rails问题,不如说是“模型设计”问题。

For clarity sake here is the business logic: I've Venues and I want to implement multiple APIs to get data about those venues. 为了清楚起见,这里是业务逻辑:我有Venues,我想实现多个API以获取有关这些场所的数据。 All this APIs have a lot in common, therefore I used STI. 所有这些API都有很多共同点,因此我使用了STI。

# /app/models/venue.rb
class Venue < ApplicationRecord
  has_one :google_api
  has_one :other_api
  has_many :apis
end

# /app/models/api.rb
class Api < ApplicationRecord
  belongs_to :venue
end

# /app/models/google_api.rb
class GoogleApi < Api
  def find_venue_reference
    # ...
  end
  def synch_data
    # ...
  end
end

# /app/models/other_api.rb
class OtherApi < Api
  def find_venue_reference
    # ...
  end
  def synch_data
    # ...
  end
end

That part works, now what I'm trying to add is Photos to the venue. 该部分有效,现在我要添加的是会议场地的照片。 I will be fetching those photos from the API and I realise that every API might be different. 我将从API中获取这些照片,并且我意识到每个API可能都不同。 I thought about using STI for that as well and I will end up with something like that 我也考虑过使用STI,最终我会得到类似的结果

# /app/models/api_photo.rb
class ApiPhoto < ApplicationRecord
  belongs_to :api
end

# /app/models/google_api_photo.rb
class GoogleApiPhoto < ApiPhoto
  def url
    "www.google.com/#{reference}"
  end
end

# /app/models/other_api_photo.rb
class OtherApiPhoto < ApiPhoto
  def url
    self[url] || nil
  end
end

My goal being to have this at the end # /app/models/venue.rb class Venue < ApplicationRecord has_one :google_api has_one :other_api has_many :apis has_many :photos :through => :apis end 我的目标是在终端#/app/models/venue.rb类地点<ApplicationRecord has_one:google_api has_one:other_api has_many:apis has_many:photos:through =>:apis end

# /app/views/venues/show.html.erb
<%# ... %>
@venue.photos.each do |photo|
   photo.url
end
<%# ... %>

And photo.url will give me the right formatting that is dependent of the api it is. 而且photo.url将为我提供正确的格式,该格式取决于它所使用的api。

As I'm going deeper in the integration, something seems not right. 随着集成的深入,似乎有些不对劲。 If I had to Api the has_many :google_api_photo then every Api will have GoogleApiPhoto. 如果我必须对has_many :google_api_photo进行Api ,则每个Api都将具有GoogleApiPhoto。 What does not make sense to me. 对我来说没有什么意义。

Any idea how I should proceed from here? 知道我应该从这里继续吗?

I think I solved it. 我想我解决了。

By adding this to venue.rb 通过将其添加到venue.rb

has_many :apis, :dependent => :destroy
has_many :photos, :through => :apis, :source => :api_photos

By calling venue.photos[0].url call the right Class based on the type field of the ApiPhoto 通过调用venue.photos[0].url ,根据ApiPhototype字段调用正确的类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM