#はじめに
Railsでの中間テーブルをjquery,jsonを使って実装してみました。
*(注意:この記事は学習の一環として実装した物の一部を記事にしています。本記事には正しくない情報、方法を含んでいる可能性があります。)
##理由
個人的にあまりRailsに依存した書き方をしたくなかったのが理由でフロントエンドの勉強も踏まえて実装してみました。(Postモデルは全て非同期での実装をしてます。)
##環境
- Rails 5.2.4
- jquery
##モデル構成
*Userモデル作成済み前提
(Post.rb)
- has_many :post_categroies, dependent: :destroy
has_many :categories, through: :post_categories
(Post_category.rb 中間テーブル)
- belongs_to :post
belongs_to :category
(Category.rb seed.rbにカテゴリー名登録済み)
- has_many :post_cates, dependent: :destroy
has_many :posts, through: :post_cates
Post | Post-category | Category |
---|---|---|
中間テーブル | ||
id | id | id |
content | post_id | name |
image | category_id | something |
##チェックボックス
Postモデルに関してはタイトル通り、Rails依存を避けるために
Formから受け取った値からPostコントローラへのCSRFトークン認証はprotect_from_forgery :exceptにしてCSRF認証トークンを使っておりません。
<div class="field form-group form-catpy">
<%=f.label :category_name, "*カテゴリーを選択してください"%><br/>
<%= f.collection_check_boxes(:category_ids, Category.all, :id, :category_name) do |category|%>
<%=category.label %>
<%= category.check_box%>
<%end%>
</div>
この部分は同じです。
##フォームの値を送る
json形式でコントローラ先に送る説明は省略します。
$("#save-button").on("click", function () {
//チェックしたカテゴリーのidを配列に格納
var checks = [];
$("[name= 'post[category_ids][]']:checked").each(function() {
checks.push(this.value);
});
$.ajax({
url: "/generate", //指定したアクションに送る
type: "POST",
dataType: "json",
async: true,
data: {
content: textVal,
category_ids: checks, //ここに注目!!
},
}).done(function(data){
//以下省略
})
});
__category_ids: checks__の場所に注目してください。筆者はこの部分にめちゃくちゃはまりました。paramsで送る名前を__f.collection_check_boxes__のプロパティ名に合わせないと読み取ってくれないらしいです。
あとjsonの場合、check_boxesにチェックしたidは、["1", "7", "8"]といったダブルクォーテーションで配列の中のidが囲まれているので中間テーブル(__post_id, category_id)に保存されないんじゃないかと思っていましたがうまく保存することができました。
あとは、Railsの中間テーブルの実装手順と同じです。
def post_params
params.permit(:content, :image_title, :post_image, :film_date,:post_url,:overview, {category_ids: []} )
end
最後に保存するとPost.rb,category.rbに紐付いた中間テーブル内にpost_id,category_idが保存されると思います。
以上です。
##最後に
json形式でPOSTする方法は省略しましたがjquery.jsonで実装してみたい、あまりRailsに依存した書き方をしたくない僕みたいな人の手助けになれば幸いです。