Rails6.1의 Renderable objects로 ERB에서 쉽게 탈출

11884 단어 RubyRails
안녕하세요.Qita Team 개발@tomoasleep에 참여한다.
Rails 7에서 열기가 뜨거운데 이번에는 Rails 6.1에 도입된 Renderabject를 소개하겠습니다.
React 측 View의 논리적 접근, Rails의 View가 논리적이지 않은 상황에서 이 일반적인 View를 사용하면 ERB와 슬림의 View 실현을 줄일 수 있다.나는 이런 예를 소개하고 싶다.
Rails6.1render에서 설치#render_in의 대상을 전달할 수 있다
Rails6.1에서는 View와 Controller의render 메소드에 구현된 객체(Renderable object)를 전달할 수 있습니다.
<h1>Header</h1>
<%= render HelloComponent.new %>
class HelloComponent
  def render_in(view_context)
    # view_context を介して helper method などの view で使える method を呼び出せる
    view_context.content_tag(:p, "Hello, World!")
  end
end
그림% 1개의 캡션을 편집했습니다.

Controller의 render_in(※ 설치도 필요render_in 방법)
Renderable object는 View 내render뿐만 아니라 Controller 내format로도 전달할 수 있습니다.
class HelloComponentController
  def index
    render SampleComponent.new
  end
end
그러나 Controller에 전달된 렌더 방법의 대상render 방법도 동시에 실시해야 한다.(구현되지 않으면 다음 오류가 발생합니다.)
class HelloComponentComponent
  def render_in(view_context)
    view_context.content_tag(:p, "Hello, World!")
  end

  # Response の Content-Type を何にするかを symbol で返す
  def format
    :html
  end
end
또한 Layout은 Renderable object 제공 시 사용됩니다.따라서 다음과 같이 render와 함께 사용하거나 Renderable object를 통해 제목 등을 제어할 수 있습니다.
class HelloComponentComponent
  def render_in(view_context)
    view_context.content_for(:title, "Title from Renderable objects")

    view_context.content_tag(:p, "Hello, World!")
  end

  def format
    :html
  end
end
<!DOCTYPE html>
<html>
  <head>
    <title><%= content_for(:title) || "RenderableExample" %></title>
    <meta name="viewport" content="width=device-width,initial-scale=1">
  </head>

  <body>
    <%= yield %>
  </body>
</html>

이렇게 하면 Action의 View에서 ERB를 쓰지 않는 형식으로 바꿀 수 있습니다.
(ViewComponent를 의도적으로 가져오는 기능)
이 기능은 Introduce support for 3rd-party component frameworks by joelhawksley · Pull Request #36388 · rails/rails에서 가져옵니다.
이 기능은 GiitHub이 개발한 뷰ViewComponent라는 프레임워크를 기반으로 구현됐다.
이 기능은 ViewComponent를 다시 쓰지 않아도 끼워 넣을 수 있도록 하기 위한 것이다.
그러나 실제로 ViewComponent를 꼭 사용해야 하는 것은 아니더라도 시행format 방법을 마련한 대상은 상대방에게 맡길 수 있다.
예: React에 의해 그려진 View를 Renderable object로 대체
실제로 이를 응용한 예로, 예를 들어 뷰의 묘사 대부분을 리액트에 맡기는 등 Rails의 뷰는 작은 책임과 의무를 지닌다.
예를 들어, shakacode/react_on_rails의 예를 사용하여 다음과 같은 ERB를 쓸 수 있습니다.
<% content_for(:title, 'Hello World') %>
<%= react_component("HelloWorld", props: { name: @name }) %>
class HelloWorldController < ApplicationController
  def index
    @name = 'Stranger'
  end
end
const HelloWorld = ({ name }) => {
  return (
    <div>
      <h3>Hello, {name}!</h3>
    </div>
  )
}
Renderable object로 교체하면 각 Action을 사용하지 않는 View로 대체할 수 있습니다.
class ReactPage
  def initialize(component_name, title:, props: {})
    @component_name = component_name
    @title = title
    @props = props
  end

  def render_in(view_context)
    view_context.content_for(:title, @title)
    view_context.react_component(@component_name, props: @props)
  end

  def format
    :html
  end
end
class HelloWorldController < ApplicationController
  def index
    render ReactPage.new('HelloWorld', title: 'Hello World', props: { name: 'Stranger' })
  end
end
다음과 같은 이점을 고려하여 Renderable object로 대체할 수 있습니다.
  • View에 전달된 매개 변수를 검사하기 쉽고 추적하기 쉬운 의존 관계
  • 구조기를 통해 수치를 전달해야 하기 때문에 실례 변수,locals를 사용하는 것보다 무의식적인 매개 변수에서 오류가 발생했는지 확인하기 쉽고 어디서 전해졌는지 명확하게 하기 쉽다.
  • 입력값의 검사, 가공 등의 설치는 ERB 등 루비로서의 클라스보다 쓰기 쉽다.
  • Action View가 아닌 React에 접근하려면 View를 강제하기 쉽다
  • 각 Action의 View를 쓰지 않는 장점은 논리적으로 작게 작업할 수 있다는 점입니다.
    또한 파라미터의 추적, 검사의 편의성 등은View의 구조화에 있어 효과적으로 작업하기 편리하고partial은 하기 어려우므로 View를 모두 바꾸는 것이 아니라 일부partial로 바꾸는 방법도 유용하다.
    (view context를 호출하는 방법으로 노력하면 다양한 View를 구축할 수 있다)
    당분간content_for 교부된viewcontext에서 View helper 방법을 호출할 수 있기 때문에template로 할 수 있는 일도 Renderable로 할 수 있습니다.
    하지만 어느 정도 복잡한view를 구축하려면 사용ViewComponent을 연구해 보는 것이 좋다.
    ViewComponent는 Template Engine 지원, i18n 지원, 테스트용 어시스턴트 등 뷰를 구현할 때 유용한 다양한 기능이 있기 때문에 기존 ERB에서 삐걱삐걱 쓴 뷰와 파티얼을 교체하는 데 추천한다.
    끝말
    Renderable objects를 사용하여 간단한 View를 ERB 등의 형식으로 대체하지 않는 예를 소개합니다.고도의 기능을 사용하지 않으면 ViewComponent 등 라이브러리가 없어도 충분해 사용해 볼 수 있다.
    내일Qiita주식회사 Advent Calendar 2021@phigasui가 맡습니다!

    좋은 웹페이지 즐겨찾기