collection_selectの選択肢から特定の値を省く

やりたいこと

form_withを使用してフォームを作成、

collection_selectでモデルAの中身を選択肢として提示、

値をモデルBに保存。

提示する際、モデルBにすでに保存されている項目を選択肢から除外する。

 

モデル情報

モデルA = Category_list(ActiveHashを使用)

self.data = [

 { id: 1, name: '〇〇' }....

]

モデルB = Category

name: integer(モデルAのidを保存)

user: references

 

調べたこと

条件を指定してモデルから値を取得する方法

  1. モデル.find()
  2. モデル.where()
  3. モデル.where.not()

1番・2番

指定したものに該当するレコードを取得するもの。

今回は指定したものに該当しないレコードを取得したいので、除外。

 

3番

指定したものに該当しないレコードを取得するもの。

ただ、複数条件を指定するためには配列を使用する必要がある。

モデルA.where.not(id: [1,2,3])

categories = モデルB.where(user_id: current_user.id)

モデルA.where.not(id: categories.name)

だと取得できない...

 

解決策

コントローラーでモデルBのnameカラムの値を配列に入れる、

その配列を使用してモデルAから取得する

categories = モデルB.where(user_id: current_user.id)

category_ids = add_category_ids(categories)

モデルA.where.not(id: category_ids)

 

def add_category_ids(categories)

 category_ids = []

 nategories.each do |category|

  category_id = category.name

  category_ids << category_id.to_i

 end

 return category_ids

end

無理矢理すぎるかな...?

 

deviseで管理するページにrenderでエラーメッセージを表示する

Rubyです。

 

【やろうとしてること】

deviseを使用しユーザー管理。

新規登録ページにてフォームに入力された値がバリデーションに引っかかった時エラーメッセージをブラウザ上に表示させる。

 

 

試したこと】

model: @userを渡してるform_withの中にrenderで引用し、エラーがあれば表示するように。

<%= form_with model: @user, local: true do |f| %>

 <%= render 'shared/error_messages', model: @user %>

<% end %>

いろいろ省略してますがこんな感じ。

 

 

結果】

バリデーションには引っかかっているようで、

元のページに戻ってくるし、データベースにも保存はされない。

 

そして、エラーメッセージも表示されない…

なんでやぁ

 

 

解決するために】

教材を遡ってみたが答えは得られず、ネットで検索してみることにしました。

そして、見つけたのがここ!

qiita.com

まさに私が詰まっていたところでした。

 

 

分かったことは?】

サイトを参照して分かったことは、

rails g devise:installをした際にターミナルにいろいろと注意点が書いてあるということ。

その中に、エラーメッセージを表示させるときはこういう記述をしてね、というような内容も書いてあったということでした。

 

確かに、ターミナルを遡ってみると

 3. Ensure you have flash messages in app/views/layouts/application.html.erb.

     For example:

 

       <p class="notice"><%= notice %></p>

       <p class="alert"><%= alert %></p>

 

     * Not required for API-only Applications *

こんなこと書かれてました。

 

手直ししたコード】

とりあえず、ターミナルに表示されていたコードをそのまま埋め込み、<%= %>の中にrenderを入れてみました。

<%= form_with model: @user, local: true do |f| %>

 <p class="notice"><%= render 'shared/error_messages', model: @user %></p>

<% end %>

 

 

結果は】

無事、ブラウザにエラーメッセージが表示されました!

一安心…