ruby-on-railsruby-on-rails-4railtie

Railtie(gem): How do i include and render erb partials?


I'm working on a Railtie(gem) for embedding videos like YouTube, Vimeo etc.

In this gem i want to have a view helper, so that i can call embed_video(embeddable, width, height)

So i have created the helper as a helper, and it works, but i would like to refactor it to use partials to make it cleaner, but i'm finding it hard to do this.

The helper:

module ViewHelpers
  def embed_video(embeddable, width, height)
    if embeddable.video_on_youtube?
      content_tag :iframe, nil, width: width, height: height,
        src: "//www.youtube.com/embed/#{embeddable.video_id}",
        allowfullscreen: true, frameborder: 0
    elsif embeddable.video_on_vimeo?
      content_tag :iframe, nil, width: width, height: height,
        src: "//player.vimeo.com/video/#{embeddable.video_id}",
        webkitallowfullscreen: true, mozallowfullscreen: true,
        allowfullscreen: true, frameborder: 0
    elsif embeddable.video_on_dailymotion?
      content_tag :iframe, nil, width: width, height: height,
        src: "//www.dailymotion.com/embed/video/#{embeddable.video_id}",
        webkitallowfullscreen: true, mozallowfullscreen: true,
        allowfullscreen: true, frameborder: 0
    elsif embeddable.video_on_veoh?
      %Q{
        <object width='#{width}' height='#{height}' id='veohFlashPlayer' name='veohFlashPlayer'>
          <param name='movie' value='http://www.veoh.com/swf/webplayer/WebPlayer.swf?version=AFrontend.5.7.0.1446&permalinkId=#{embeddable.video_id}&player=videodetailsembedded&videoAutoPlay=0&id=anonymous'></param>
          <param name='allowFullScreen' value='true'></param>
          <param name='allowscriptaccess' value='always'></param>
          <embed src='http://www.veoh.com/swf/webplayer/WebPlayer.swf?version=AFrontend.5.7.0.1446&permalinkId=#{embeddable.video_id}&player=videodetailsembedded&videoAutoPlay=0&id=anonymous' type='application/x-shockwave-flash' allowscriptaccess='always' allowfullscreen='true' width='#{width}' height='#{height}' id='veohFlashPlayerEmbed' name='veohFlashPlayerEmbed'>        </embed>
        </object>
      }.html_safe
    #
    # And more providers...
    #
  end
end

With the use of partials i want to write it like this:

module ViewHelpers
  def embed_video(embeddable, width, height)
    if embeddable.video_on_youtube?
      render 'youtube', embeddable: embeddable, width: width, height: height
    elsif embeddable.video_on_veoh?
      render 'veoh'#...etc
    end
  end
end

My attempted solution:

Add view paths in railtie.rb

module Embeddable
  class Railtie < Rails::Railtie
    # ...load view helpers... #

    initializer 'embeddable.add_autoload_paths', :before => :set_autoload_paths do |app|
      app.config.autoload_paths << app.root.join("lib/embeddable/partials").to_s
    end

    # My attempt at adding the partials to the view path
    initializer 'embeddable.add_view_paths', :after => :add_view_paths do |app|
      ActiveSupport.on_load(:action_controller) do
        append_view_path app.root.join("lib/embeddable/").to_s
      end
    end
  end
end

When i try to render the view i get the following error:

ActionView::MissingTemplate: Missing partial partials/veoh with {:locale=>[:nb], :formats=>[:html], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :rabl, :haml]}. Searched in:
  * "/home/me/Arbeid/the_application/app/views"
  * "/home/me/.rvm/gems/ruby-2.1.0/gems/kaminari-0.15.1/app/views"
  * "/home/me/Arbeid/the_application/lib/embeddable"

Solution

  • After a lot of trail and error i managed to get it working. This is what i had to do:

    I changed this:

    initializer 'embeddable.add_view_paths', :after => :add_view_paths do |app|
      ActiveSupport.on_load(:action_controller) do
        append_view_path app.root.join("lib/embeddable/").to_s
      end
    end
    

    Into this:

    initializer 'embeddable.add_view_paths', :after => :add_view_paths do |app|
      ActiveSupport.on_load(:action_controller) do
        append_view_path "#{Gem.loaded_specs['embeddable'].full_gem_path}/lib/embeddable"# <- this is the change
      end
    end
    

    Now i can render partials from the helper like this:

    render 'partials/youtube', id: video_id, width: width, height: height