2019-01-22

RubyのCellsのv4以降の使い方メモ

trailblazer/cells: View components for Ruby and Rails.

主に v2 以前から使っていた人向け。なんかずーっと ViewModel という言葉に引っかかっていたんだけど、ちょっと分かったかも。

まずは基本の使い方から。

定義

class SampleCell < Cell::ViewModel
  ..
end

呼び方

micro MVC 的な呼び方

cell(:<name>[, :<model>]).(:<state>[, options])

これで Cell の中のメソッドを読んだ結果を String として(to_sして)出力できる。View の中で micro MVC として使う Cells v2 以前の render_cell() 時代の使い方のイメージ。

ただのCellオブジェクトを取得する呼び方

cell(:<name>[, :<model>])

これで文字列になる前のただの初期化済み Cell オブジェクトが取得できる。

Cellの実体は.()でcallさせると安全にto_sできるオブジェクト

Cells は定義の部分よりは呼ぶ部分の方がちょっと気持ち悪い。まずマジカルさの一つは

cell().()

という見慣れない書き方なのだが、この .() は call() の syntax sugar だった。

Ruby | 「call」メソッド の Syntax Sugar 「.()」 について - Qiita

では call はどうなっているかというと、以下のようになっている。

     def call(state=:show, *args, &block)
       content = render_state(state, *args, &block)
       content.to_s
     end

call すると render して to_s している。1

さらに

   def to_s
     call
   end

が定義されているので、 String として評価される context ではマジカルに #show が呼ばれ、view を render して何かが出力されるという算段になっている。

これを意図して rails generator で cell を作ると、まず

def show
  render
end

だけを持つ class ができる。

ということで、「なんかいい具合に to_s するための仕組みの入っているオブジェクト」というのが Cells の実体と言ってよさそう。

一つ気をつけなきゃいけないのが、Cells は View ではなく Controller の context で実行されているということ。もう一つ、v4 以降の Cells は Rails 非依存なので、Controller を継承していない。cells-rails gem では関連 module はいろいろ include しているが、Controller を継承していることは前提にしてはいけない。

で、ViewModelとして扱うってどうよ?

Controller から View 向けのロジックを追い出すために Cells を使うとよいと「伝統的なサーバサイドWeb開発アンチパターンとその対策 - C, V編 - - あーありがち(2019-01-20)」に書いたが、Cells で本当によいのだろうか?という疑問は感じるかもしれない。むしろ PORO ( Plain Old Ruby Object ) の方がよいという意見もあるのではないかと思う。

結論から言うと PORO でもよいと思う。

ただ View 側に渡しやすい何かにするための ViewModel なはずなので、最初からそういう仕組みの用意されている Cells にしておけば自動的に置き場所も決まるし、安全に to_s されるし、独自の template を追加することもできるし、Helper も呼べるし、testability も考慮されてるし、まーだいたいよいことづくめだと思う。どうせ何らかの支援は欲しくなるはずだ。

個人的には Cell という名前だけが非常に引っかかっていて、どうしても micro MVC を用意するイメージが強いので、いっそのこと

app/cells/*_view_model.rb

みたいな名前付けで置いといて2、呼び方も

FooViewModel.new

みたいにしておくと、呼ぶ側からは明らかに render_cell の頃のアレとは違う使い方をしている感 が出るのでよいかもしれない。

これなら micro MVC 的な Cells と ViewModel を使い分けている感じをさせつつ、使っているツールは一つに絞れる。

  1. cells-rails ではこれをさらに html_safe している 

  2. app/view_models/ でもよいが 

About

例によって個人のなんちゃらです

Recent Posts

Categories

Tool 日々 Web Biz Net Apple MS ことば News Unix howto Food PHP Movie Edu Community Book Security Text TV Perl Ruby Music Pdoc 生き方 RDoc ViewCVS CVS Rsync Disk Mail FreeBSD Cygwin PDF Photo Zebedee Debian OSX Comic Cron Sysadmin Font Analog iCal Sunbird DNS Linux Wiki Emacs Thunderbird Sitecopy Terminal Drawing tDiary AppleScript Life Money Omni PukiWiki Xen XREA Zsh Screen CASL Firefox Fink zsh haXe Ecmascript PATH_INFO SQLite PEAR Lighttpd FastCGI Subversion au prototype.js jsUnit Apache Trac Template Java Rhino Mochikit Feed Bloglines CSS del.icio.us SBS qwikWeb gettext Ajax JSDoc Rails HTML CHM EPWING NDTP EB IE CLI ck ThinkPad Toy WSH RFC readline rlwrap ImageMagick epeg Frenzy sysprep Ubuntu MeCab DTP ERD DBMS eclipse Eclipse Awk RD Diigo XAMPP RubyGems PHPDoc iCab DOM YAML Camino Geekmonkey w3m Scheme Gauche Lisp JSAN Google VMware DSL SLAX Safari Markdown Textile IRC Jabber Fastladder MacPorts LLSpirit CPAN Mozilla Twitter OpenFL Rswatch ITS NTP GUI Pragger Yapra XML Mobile Git Study JSON VirtualBox Samba Pear Growl Mercurial Rack Capistrano Rake Win RSS Mechanize Sitemaps Android JavaScript Python RTM OOo iPod Yahoo Unicode Github iTunes God SBM friendfeed Friendfeed HokuUn Sinatra TDD Test Project Evernote iPad Geohash Location Map Search Simplenote Image WebKit RSpec Phone CSV WiMAX USB Chrome RubyKaigi RubyKaigi2011 Space CoffeeScript Nokogiri Hpricot Rubygems jQuery Node GTD CI UX Design VCS Kanazawa.rb Kindle Amazon Agile Vagrant Chef Windows Composer Dotenv PaaS Itamae SaaS Docker Swagger Grape WebAPI Microservices OmniAuth HTTP 分析基盤 CDN Terraform IaaS HCL Webpack Vue.js BigQuery Middleman CMS AWS PNG Laravel Selenium OAuth OpenAPI GitHub UML GCP TypeScript SQL Hanami Document SVG AsciiDoc Pandoc DocBook Develop Jekyll macOS Node.js Vite Heroku Transformer AI Data Cloud Wasm