Help us understand the problem. What is going on with this article?

RailsにReactやVueは不要!? ajaxでviewを非同期で操作するgem(ActionPartial)を作りました。

ActionPartial

個人でCrover(クリエイターズプラットフォーム)というサービスを企画&開発&運営しているnirと申します。

Croverの開発で動的なviewの実装が必要になったので、gemを作ることにしました。

それで出来上がったのが、Railsで動的なviewを簡単に実現できるgemActionPartialです。

Crover(クリエイターズプラットフォーム)
https://crover.me

github(ActionPartial)
https://github.com/nir-searchright/actionpartial

なぜ、ReactVueを使わなかったかというと
- 学習コストが高い
- フレームワークにフレームワークを組み込むことに違和感がある
- 設計思想的な問題(RailsRailsのまま使いたい)

自分だけで使うはもったいないので、とりあえず公開することにしました。

注意)
- ReactVueを否定する記事ではありません。

DEMO

簡易的なデモを作成したのでご自由にお試しください。

デモ
https://actionpartial-demo.herokuapp.com

github(ActionPartial DEMO)
https://github.com/nir-searchright/actionpartial_demo

herokuの無料プランなのでデモのページを開くのに時間がかかるかもしれません。

ここから先はデモを元に説明します。

導入方法

Gemfile'actionpartial', github: 'nir-searchright/actionpartial'を追加してbundle installします。

現状、RubyGemsには登録していないのでgithuburlは必須です。

gem 'actionpartial', github: 'nir-searchright/actionpartial'

application_helper.rbrequireするだけで準備は完了です。

application_helper.rb
require 'action_partial'

ActionPatialができること

ActionPartialができることは

  • partialの更新
  • partialの追加
  • partialの削除

これらの単純な機能だけです。

単純故に応用も利きやすい設計となっているはずです。(多分)

demo_a.gif

仕組み

前提として、Railsではlink_toformremote: trueをつけるとajaxで通信が行われます。

<%= form_for(@post, remote: true) do |f| %>
  内容
<% end %>

ajaxでリクエストを送り、サーバーからxxx.js.erbを返します。

def create
  内容
  render 'posts/js_erb/create.js.erb'
end

サーバーから返されたxxx.js.erbview
- innerHTMLpartialを更新(https://developer.mozilla.org/ja/docs/Web/API/Element/innerHTML)
- insertAdjacentHTMLで任意の位置にpartialを挿入(https://developer.mozilla.org/ja/docs/Web/API/Element/insertAdjacentHTML)
- removepartialを削除(https://developer.mozilla.org/ja/docs/Web/API/ChildNode/remove)
などをしています。

helperメソッド一覧

html.erbで使うヘルパー

index.html.erb
<%= ap_render "posts/list/container", class: "posts-padding-bottom", locals: {posts: @posts} %>
<%= ap_render "posts/new" %>

<%= ap_init(path, options={}) %>

  • 最初は表示したくないけど、後からコンテンツを追加したい場所に使います。
  • エラーメッセージなどの後から表示する要素に使います。

<%= ap_render(path, options={}) %>

  • 非同期で更新したいpartialrenderするのに使います。
  • 基本的にRailsが提供するrenderと大して変わりません。

js.erbで使うヘルパー

※サンプルコードは下の個別の説明に載せてあります。

<%= ap_before(path, options = {}) %>

  • ap_initもしくはap_renderしたpartialの外側上部にpartialが挿入されます。

<%= ap_prepend(path, options = {}) %>

  • ap_initもしくはap_renderしたpartialの内側上部にpartialが挿入されます。

<%= ap_append(path, options = {}) %>

  • ap_initもしくはap_renderしたpartialの内側下部にpartialが挿入されます。

<%= ap_after(path, options = {}) %>

  • ap_initもしくはap_renderしたpartialの外側下部にpartialが挿入されます。

<%= ap_replace(path, options = {}) %>

  • ap_initもしくはap_renderしたpartialがサーバーから取得した新しいpartialに置換されます。

<%= ap_remove(id) %>

  • html上に存在する要素をid指定で削除します。

基本の使い方

基本は更新or追加or削除したいpartialid(ap_initもしくはap_renderした場合はpartialpath名)を指定して使います。

partialでインスタンス変数を使っている場合はlocalsで変数を渡します。

add.js.erb
<%= ap_append("posts/list/loop", locals: {posts: @posts}) %>

詳しくはDEMOのadd.js.erbをご確認ください。(このコードは無限スクロールのコードです。)
add.gif

他の要素やpartialpartialを追加(挿入)したい場合

追加したい要素やpartialid(ap_initもしくはap_renderした場合はpartialpath名)を指定することでpartialの追加(挿入)が可能です。

create.js.erb
<%= ap_prepend("posts/list/item", id: "posts/list/loop", class: "posts-list-item", locals: {post: @post}) %>

詳しくはDEMOのcreate.js.erbをご確認ください。(このコードは新規投稿のコードです。)

create_a.gif

複数のpartialから一つのpartialを指定したい場合

js.erbで使えるヘルパーはoptionidを指定することができます。

例えばhtml.erbでこんな感じでeachで回しながらコンテンツにidを指定することでjs.erbでコンテンツを指定することが可能です。

<% posts.each do |post| %>
  <div id="posts_<%= post.id %>">
    内容
  </div>
<% end %>

詳しくはDEMOのupdate.js.erb destroy.js.erb calcel.js.erbをご確認ください。

update_a.gif
delete_a.gif

jsの実行

当たり前と言えば当たり前ですがjs.erbjsのコードを書いておけば一緒に実行できます。

create.js.erb
<%= ap_prepend("posts/list/item", id: "posts/list/loop", class: "posts-list-item", locals: {post: @post}) %>

document.getElementById("post_content").value = "";
scrollTo(0, 0);

ただ、このjsが実行できてしまう仕組みがセキュリティ的に良いのかは分かりません。

理論上だとhttps通信をしているなら問題ないはずですが、どうなのでしょうか?

どなたか詳しい方がいればコメントで教えていただけると助かります。

最後に

今回やったことは「ネット上でよく見かけるjs.erbでの非同期更新を簡単に使えるようにgem化した」だけです。

作ってみて思ったよりも使いやすかったのでとりあえず公開しました。

ActionPartialは学習コスト低めでhtmljsrailsだけ理解していれば使えるのでスピーディーな開発ができると思います。

スピードを重視するスタートアップのプロジェクトとの相性が良いのではないでしょうか?

機能的にはシンプルなgemなので導入で不具合を吐くことはほとんどないと思います。

そのうち気が向いたらrails ujsを使ったコンテンツの非同期更新の記事もアップします。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした