有条件地包括实例方法

时间:2014-03-17 07:02:15

标签: ruby-on-rails ruby-on-rails-4

我有一个支持多种第三方视频服务的视频模型,例如Youtube,Vimeo和Livestream。

用户创建新视频并选择该视频的服务和ID。

在我的视频模型中,我的方法有很多case语句,具体取决于使用的服务。

E.g。

class Video

  def video_duration
    case service
      when 'Vimeo'
        Time.at(duration).utc.strftime("%-l:%M:%S")
      when 'Livestream'
       'Ongoing'
    end
  end

end

理想情况下,我希望每个服务都有一个模块,其中包含实例方法,可以根据选择的视频服务将其包含在模型中。可以这样做吗?

我考虑过继承虽然这看起来很痛苦,因为它改变了视图中引用每个东西的方式,例如不同的类名,预期的路线等等,我都不需要。

感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

使用继承是最好的解决方案,正如Hitham所说。

编写控制器/视图没有区别,因为您处理的是实例,而不是类。

class Video < ActiveRecord::Base
  def service
    ''
  end
end

class VimeoViedo < Video
  def service
    Time.at(duration).utc.strftime("%-l:%M:%S")
  end
end

class LiveStream < Video
  def service
    'ongoing'
  end
end

# Controller
def show
  klass = params[:type].constantize
  @video = klass.find(params[:id])
end

# View
<%= @video.service %>

答案 1 :(得分:0)

继承是Billy&amp; amp; Hitham。但这并没有解决路径,CSS类名,forms_for等视图中发生的各种变化的问题。这些是基于模型model_name类方法生成的。这可以在子类中重写,如

class VimeoVideo < Video

  def self.model_name
    Video.model_name
  end

end

这会产生:

VimeoVideo.model_name

#<ActiveModel::Name:0x007f9106973800 @name="Video", @klass=Video(id: integer, title: string, .....), @singular="video", @plural="videos", @element="video", @human="Video", @collection="videos", @param_key="video", @i18n_key=:video, @route_key="videos", @singular_route_key="video"

渲染一组视频仍然需要更加具体(而不是渲染@videos):

<%= render partial: 'video', collection: @videos, as: :video %>