Try using view_component with rails

What is view_component

It is a gem made by github. https://github.com/github/view_component

It's like a power-up version of render partial, which seems to be useful when you want to reuse the view code or write tests.

Since ruby ​​and template can be prepared as a set like this, it seems that it is easier to write logic and data transfer compared to partial.

app/components/test_component.rb


class TestComponent < ViewComponent::Base
  def initialize(title:)
    @title = title
  end
end

erb:app/components/test_component.html.erb


<span title="<%= @title %>"><%= content %></span>

It looks like this when calling.

<%= render(TestComponent.new(title: "my title")) do %>
  Hello, World!
<% end %>

Apart from the defined @ title, the content passed in block is automatically assigned to the accessor called content.

Installation

You can add a gem and install it with bundle install.

gem "view_component", require: "view_component/engine"

About version

It seems to work with rails 5.0 and above. However, if it is less than rails 6.1, it seems that the render method will be patched with a monkey.

You can also use render_component if you don't want to apply the monkey patch.

config.view_component.render_monkey_patch_enabled = false # defaults to true
<%= render_component Component.new(message: "bar") %>

Creating view_component

Let's create a view_component with the rails command.

bin/rails generate component Example title

A set of files is created like this.

Running via Spring preloader in process 407
      create  app/components/example_component.rb
      invoke  test_unit
      create    test/components/example_component_test.rb
      invoke  erb
      create    app/components/example_component.html.erb

preview function

You can check view_componet in preview like ActionMailer.

test/components/previews/test_component_preview.rb



class TestComponentPreview < ViewComponent::Preview
  def with_default_title
    render(TestComponent.new(title: "Test component default"))
  end

  def with_long_title
    render(TestComponent.new(title: "This is a really long title to see how the component renders this"))
  end

  def with_content_block
    render(TestComponent.new(title: "This component accepts a block of content")) do
      tag.div do
        content_tag(:span, "Hello")
      end
    end
  end
end

Now you can check the preview by accessing the url below. http://localhost:3000/rails/view_components/test_component/with_default_title http://localhost:3000/rails/view_components/test_component/with_long_title http://localhost:3000/rails/view_components/test_component/with_content_block

How to write a test

You can test the content by calling view_component with render_inline.

require "test_helper"

class HelloComponentTest < ViewComponent::TestCase
  def test_component_renders_something_useful
    assert_equal(
      %(<div>hello bob</div>),
      render_inline(HelloComponent.new(name: "bob")).css("div").to_html
    )
  end
end

document

It seems that there are various functions other than those introduced this time, so if you are interested, please see the official document. https://viewcomponent.org/

Recommended Posts

Try using view_component with rails
Japaneseize using i18n with Rails
[Rails] Try using Faraday middleware
Try using Redis with Java (jar)
Try using libGDX
Try using Maven
Try using powermock-mockito2-2.0.2
Try using GraalVM
Try using the Rails API (zip code)
Try using jmockit 1.48
Try using sql-migrate
Try using Spring Boot with VS Code
Notes on using FCM with Ruby on Rails
Try using SwiftLint
Try using Log4j 2.0
Try using Kong + Konga with Docker Compose.
Try using the Wii remote with Java
Using Material Design for Bootstrap with Rails 5.2
Try using GPS receiver kit with RaspberryPi3 (Ruby)
Try using S3Proxy with Microsoft Azure Blob Storage
Try using another Servlet container Jetty with Docker
Try to summarize the common layout with rails
Try DI with Micronaut
Try using Axon Framework
Try create with Trailblazer
Try using JobScheduler's REST-API
Try using java.lang.Math methods
Try using PowerMock's WhiteBox
Using Pair with OpenJDK
Rails deploy with Docker
Try WebSocket with jooby
[Rails 6] RuntimeError with $ rails s
Try using Talend Part 2
Handle devise with Rails
[Rails] Learning with Rails tutorial
Try WildFly with Docker
[Rails] Test with RSpec
[Rails] Development with MySQL
Try using Talend Part 1
Supports multilingualization with Rails!
Try using F # list
Try using each_with_index method
Double polymorphic with Rails
Try using Spring JDBC
Try using DI container with Laravel and Spring Boot
Try using OpenID Connect with Keycloak (Spring Boot application)
Multi-tenant with Rails using PostgreSQL's Row Level Security Policy
Using PAY.JP API with Rails ~ Implementation Preparation ~ (payjp.js v2)
Using PAY.JP API with Rails ~ Card Registration ~ (payjp.js v2)
Try to work with Keycloak using Spring Security SAML (Spring 5)
Try to implement tagging function using rails and js
Try using the query attribute of Ruby on Rails
Succeeded in loading js manually compiled using webpack with rails6
[Rails] Fade out flash messages with javascript without using jquery
Try using RocksDB in Java
Introduced graph function with rails
Search function using [rails] ransack
[Rails] Express polymorphic with graphql-ruby
[Rails] Upload videos with Rails (ActiveStorage)
Try DB connection with Java
SNS authentication using Rails google