質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.35%

  • Ruby on Rails

    5076questions

    Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Railsにおける記事のプレビュー機能の実装方法

受付中

回答 1

投稿 2017/11/20 13:04

flag 質問者が2日前に「まだ回答を求めています」と言っています。

  • 評価
  • クリップ 0
  • VIEW 128

minadukirein

score 77

現在、記事のプレビュー機能を実装しようと考えています。
Rails のバージョンは 4.2.6 でデータベースには MySQL 5.5 を使用しています。

知りたいこと

プレビュー機能の仕様については以下の通りです。

プレビュー機能の仕様
① 記事編集画面でプレビューボタンを押すと別タブで現在入力された内容を表示する
② プレビュー用のURLを発行し、そのURLからほかの人も同じプレビューを閲覧できる

たとえば、プレビュー用のURLは以下のようになります。
オリジナルURL:/posts/12345
プレビューURL:/posts/12345?preview=true

仕様については WordPress と似ているかもしれません。
①の実装方法は既に把握しているので、今回は②の方法について知りたいです。

データベースの構成

データベースの構成は以下の通りです。

users
 - id: integer
 - email: string
 - name: string

posts
 - id: integer
 - title: string
 - content: text
 - user_id: integer
 - updated_at: datetime

posts_tags
 - id: integer
 - tag_id: integer
 - post_id: integer

tags
 - id: integer
 - name: string

考えたこと

プレビュー機能の実装方法について以下のような方法を考えました。
まず、以下のようなプレビュー用テーブルを用意します。

preview_posts
 - id: integer
 - post_id: integer
 - title: string
 - content: text
 - user_id: integer
 - updated_at: datetime

preview_posts_tags
 - id: integer
 - tag_id: integer
 - post_id: integer

記事の新規作成ボタンを押すのと同時に空の post レコードを作成します。
これはプレビュー時に使用する URL (post_id) を作成するためです。
今後、保存時にはこの post_id のレコードに保存していきます。

また、プレビューボタンが押されたときに、 preview_posts テーブルにデータを保存し
そのデータをプレビューとして表示します。

もしプレビュー表示の URL にアクセスした場合に、プレビュー用のレコードがなかったり、
posts テーブルに保存されている更新日時が preview_posts の更新日時より新しければ、
posts に保存されている内容をプレビューとして表示します。

この方法の問題点
① 新規作成時に ID を発行するので、無駄に post_id を消費してしまう。
② 元のテーブルの構成が変更されるたびにプレビュー用のテーブルも変更しなければならない。

記事の新規作成の頻度はそれほど多くないので、①はそこまで問題にならないかもしれません。
記事のテーブル構成は今後頻繁に変更する可能性があり、テーブルの変更だけでなく
Active Record のリレーションなどの設定もしなければならないので、②は特に問題になると思います。

paper_trail などのバージョン管理用の gem を使用し、
プレビュー機能を実装することも検討しましたが、少しオーバースペックかなと思いました。
私が掲示した方法に関係なく、もし良い方法がありましたらご教授いただけると幸いです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

/posts/preview?title=XXX&content=YYY&...

というような URL で posts#preview アクションを起こして,このアクションでは

  1. create アクションのようにパラメーターを受け取り,Post.new して @post に収める(save はしない)
  2. 必要なら created_at を適当にセットする
  3. show アクションのように @post を表示する

という設計でどうでしょうか。

投稿 2017/11/29 15:08

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/29 15:14

    ご回答いただきありがとうございます!
    回答の通りパラメータに含めることで表示させることは可能です。
    しかし、記事の content が数千文字を超える可能性があるので、
    すべてをURLのパラメータとして含めることは少し現実的ではないかと思いました。

    キャンセル

  • 2017/11/29 17:52 編集

    URL の長さ制限にひっかかるのは IE くらいではないでしょうか。

    通信の問題のほかに,IE 以外のブラウザーでもアドレスバーに URL が収まらないという問題がありますが,これは Ajax を使えば解決すると思います。

    あ,IE11 に対応しないといけないのですね。

    とすると,やはり GET ではなく POST でやるのが早道ではないかと思います。

    RESTful 性に反するのではないか,と私も危惧しましたが,そもそも GET を使った場合も「リソースの取得」とは違うことをやらせているわけで,どのみち同じかという気もします。

    キャンセル

  • 2017/11/29 18:16

    コメントいただきありがとうございます!
    自分で書いた記事の内容はPOSTすれば良いので、その方法で困らないかと思いますが、
    記事のプレビューをシェアするときに困るかなと思います。

    たとえば、プレビューをほかの人に確認してもらいたいときに、
    プレビュー記事へのリンクをコミュニケーションツールやメールなどで共有すると思います。
    その場合、数千文字の長さのURLだとコミュニケーションツールの文字数制限に
    引っかかる可能性があると思いますし、単純に見栄えがあまり良くないかと思います。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.35%

関連した質問

同じタグがついた質問を見る

  • Ruby on Rails

    5076questions

    Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。