Skip to content

Rails Engine support #1945

@tkowalewski

Description

@tkowalewski

I want to use view components in Rails Engine, but component generator produces component file without module (engine) name.
We can fix this manually always after component generation :|, but there should be support for module_namespacing like in templates in Rails.

How to reproduce

Create new Rails Engine

rails plugin new dummy --mountable

Add view_component as dependency in dummy.gemspec

spec.add_dependency "view_component", "~> 3.8"

and fix dummy.gemspec specs by adding homepage, summary ...

Install gems

bundle install

Require view component library in lib/dummy/engine.rb by adding at the top

require "view_component"

Generate view component

% bin/rails generate component Example
      create  app/components/dummy/example_component.rb
      invoke  test_unit
      create    test/components/dummy/example_component_test.rb
      invoke  erb
      create    app/components/dummy/example_component.html.erb

And generated component (app/components/dummy/example_component.rb) looks like

# frozen_string_literal: true

class ExampleComponent < ViewComponent::Base
  def initialize(text:)
    @text = text
  end

end

Expected behaviour

ViewComponent should generate components within Rails Engine module like all other resources generated for Rails Engine.

Expected component

# frozen_string_literal: true

module Dummy
  class ExampleComponent < ViewComponent::Base
    def initialize(text:)
      @text = text
    end
  end
end

The fix

To generate component within Rails Engine module we should use module_namespacing method in templates.
For example lib/rails/generators/component/templates/component.rb.tt should looks like:

# frozen_string_literal: true

<% module_namespacing do -%>
class <%= class_name %>Component < <%= parent_class %>
<%- if initialize_signature -%>
  def initialize(<%= initialize_signature %>)
    <%= initialize_body %>
  end
<%- end -%>
<%- if initialize_call_method_for_inline? -%>
  def call
    content_tag :h1, "Hello world!"<%= ", data: { controller: \"#{stimulus_controller}\" }" if options["stimulus"] %>
  end
<%- end -%>
end
<% end -%>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions