CarbazochromeT / drug_app

drug_app
0 stars 0 forks source link

ラジオボタンを動くようにしたい #8

Closed CarbazochromeT closed 11 months ago

CarbazochromeT commented 1 year ago

rubyは "3.0.2"、"rails"は"7.0.6"を使用して製作しております。

中間テーブル、booleanを利用したラジオボタンが動かなくて苦戦しております。 アドバイス等頂けたら幸いです。

Image from Gyazo

上記のような、クリック判定があると色が変わるラジオボタンをHTMLとCSSで作ったため、これをRailsのラジオボタン形式で動くようにしたいです。 検索機能はRansackを用いて実装予定です。

view/drugs/search.html.erb

  <dt>車の運転はしますか?</dt>
  <dd>
    <ul class= "search-list">
      <li>
      <div class="yesno">
      <%= f.radio_button :drive_eq, true, id:'drive_ok', checked: true  %>
      <%= f.label :drive_true ,"はい", for: 'drive_ok', class:"switch-on" %>
      <%= f.radio_button :drive_eq, false, id:'drive_ng' %>
      <%= f.label :drive_false ,"いいえ",for: 'drive_ng', class:"switch-off" %>
      </div>

    <div class="yesno">
      <input type="radio" name="drive" id="drive-on" value="d-on" checked="">
      <label for="drive-on" class="switch-on">はい</label>
      <input type="radio" name="drive" id="drive-off" value="d-off">
      <label for="drive-off" class="switch-off">いいえ</label>
    </div>
      </li>
    </ul>
  </dd>
app/controllers/drugs_controller.rb

class DrugsController < ApplicationController
  skip_before_action :require_login
  before_action :set_drug,only: [:show, :edit, :update, :destroy]

  def index
  end

  def show
  end

  def search
    @q = Drug.ransack(params[:q])
    @drugs = @q.result(distinct: true).includes(:symptoms, :ingredients, :maker_names).page(params[:page]).order("created_at desc")
    @results = @q.result
  end

  def show
    @drug = Drug.find(params[:id])
    @ingredients = @drug.ingredients.includes(:ingredient).all.order(created_at: :desc)
  end

  private

  def set_drug
    @drug = Drug.find(params[:id])
  end

  def drug_params
    params.require(:drugs).permit(:id, :drug, :name, :effect_text, :usage, :document_url, :formulation, :division, :taxation, :for_days,  { symptom_ids: [] }, :ingredients, :maker_name_id, :drive)
  end

end

driveの情報はingredientsテーブルの情報を@drugのほうへ引き出したいです。 ransackを利用したコントローラーの記載が不十分なことが原因だと考えております。 :driveの記載をRansackの書き方に沿うべく:drive_eqに直したりもしましたが、うまくいきませんでした。 driveが別テーブルに存在するため、permitを利用してもその情報がうまく行き渡っていないこと、drug_paramsの情報を引き出せていないことが原因かなと思っております。

エラーメッセージ

Started GET "/search" for ::1 at 2023-08-24 07:04:08 +0900
  ActiveRecord::SchemaMigration Pluck (0.2ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
Processing by DrugsController#search as HTML
  Rendering layout layouts/application.html.erb
  Rendering drugs/search.html.erb within layouts/application
  Symptom Load (0.6ms)  SELECT "symptoms".* FROM "symptoms"
  ↳ app/views/drugs/search.html.erb:41
  Rendered drugs/search.html.erb within layouts/application (Duration: 274.2ms | Allocations: 41666)
  Rendered layout layouts/application.html.erb (Duration: 275.6ms | Allocations: 42030)
Completed 500  in 621ms (ActiveRecord: 2.3ms | Allocations: 150547)

ActionView::Template::Error (undefined method `drive' for Ransack::Search<class: Drug, base: Grouping <combinator: and>>:Ransack::Search):
    72:       <div class="yesno">
    73:       <%= f.radio_button :drive, true, id:'drive_ok', checked: true  %>
    74:       <%= f.label :drive_true ,"はい", for: 'drive_ok', class:"switch-on" %>
    75:       <%= f.radio_button :drive, false, id:'drive_ng' %>
    76:       <%= f.label :drive_false ,"いいえ",for: 'drive_ng', class:"switch-off" %>
    77:       </div>
    78: 

app/views/drugs/search.html.erb:75
app/views/drugs/search.html.erb:17

関連コード

models/drug.rb

class Drug < ApplicationRecord
  extend Enumerize
  has_many :drug_ingredients,dependent: :destroy
  has_many :ingredients,through: :drug_ingredients
  has_many :drug_symptoms, dependent: :destroy
  has_many :symptoms, through: :drug_symptoms
  belongs_to :maker_name

  enumerize :formulation, in: { tablet: 0, powder: 1, capsule: 2, liquid: 3, nose: 4 }, multiple: true
  enum :division, { to_guide: 0, one_kind: 1, two_kind: 2, three_kind: 3, two_designate: 4 }

end
models/ingredient.rb

class Ingredient < ApplicationRecord
  extend Enumerize
  has_many :drug_ingredients, dependent: :destroy, foreign_key: 'ingredient_id'
  has_many :drugs,through: :drug_ingredients

  validates :name, uniqueness: true, presence: true

  enumerize :drive, in: { drive_ok: true, drive_ng: false }
  enumerize :tobacco, in: { tobacco_ok: true, tobacco_ng: false }
  enumerize :alcohol, in: { alcohol_ok: true, alcohol_ng: false }

  def self.search(search_params)
        @drug = Drug.where( 'drive LIKE ?', "%#{search_params[:search_radio]}%" )
  end
end
class DrugIngredient < ApplicationRecord
  belongs_to :drug
  belongs_to :ingredient
  validates :drug_id, presence: true
  validates :ingredient_id, presence: true
end
schema.rb

# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# This file is the source Rails uses to define your schema when running `bin/rails
# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
# be faster and is potentially less error prone than running all of your
# migrations from scratch. Old migrations may fail to apply correctly if those
# migrations use external dependencies or application code.
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.0].define(version: 2023_08_23_043949) do
  create_table "drug_ingredients", force: :cascade do |t|
    t.integer "drug_id"
    t.integer "ingredient_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["drug_id", "ingredient_id"], name: "index_drug_ingredients_on_drug_id_and_ingredient_id", unique: true
    t.index ["drug_id"], name: "index_drug_ingredients_on_drug_id"
    t.index ["ingredient_id"], name: "index_drug_ingredients_on_ingredient_id"
  end

  create_table "drug_symptoms", force: :cascade do |t|
    t.integer "drug_id"
    t.integer "symptom_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["drug_id", "symptom_id"], name: "index_drug_symptoms_on_drug_id_and_symptom_id", unique: true
    t.index ["drug_id"], name: "index_drug_symptoms_on_drug_id"
    t.index ["symptom_id"], name: "index_drug_symptoms_on_symptom_id"
  end

  create_table "drugs", force: :cascade do |t|
    t.string "name", null: false
    t.string "effect_text"
    t.string "usage"
    t.string "document_url"
    t.integer "formulation"
    t.integer "division"
    t.boolean "taxation", default: false, null: false
    t.integer "for_days"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer "maker_name_id"
  end

  create_table "ingredients", force: :cascade do |t|
    t.string "name", null: false
    t.boolean "drive", default: false, null: false
    t.boolean "tobacco", default: false, null: false
    t.boolean "alcohol", default: false, null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "maker_names", force: :cascade do |t|
    t.string "name", null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "symptoms", force: :cascade do |t|
    t.string "name", null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "users", force: :cascade do |t|
    t.string "email", null: false
    t.string "crypted_password"
    t.string "salt"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "username"
    t.boolean "admin", default: false
    t.index ["email"], name: "index_users_on_email", unique: true
  end

  add_foreign_key "drug_ingredients", "drugs"
  add_foreign_key "drug_ingredients", "ingredients"
  add_foreign_key "drug_symptoms", "drugs"
  add_foreign_key "drug_symptoms", "symptoms"
end

参考文献

https://qiita.com/RouxRhett/items/7c2bd566c4f3ee0d6281 https://mstssk.hatenablog.com/entry/2020/05/07/211108 https://blog.turai.work/entry/20191016/1571155260 https://qiita.com/kajikaji/items/cf0bcf9a3d689d6b07b2

Tsuchiya2 commented 1 year ago

確認ですが、「ラジオボタンが動かなくて苦戦しております」は、"はい"・"いいえ"をクリックした際にアクティブ状態が切り替わらないということでしょうか?それともデータの保存が上手くいかないということでしょうか?

クリック判定があると色が変わるラジオボタンをHTMLとCSSで作ったため、これをRailsのラジオボタン形式で動くようにしたいです。

こちらの記述からも"いいえ"状態から"はい"をクリックすると、"いいえ"が非アクティブになり、"はい"がアクティブ状態になるようにしたい認識を抱いたのですが合っていますでしょうか?

view/drugs/search.html.erb

  <dt>車の運転はしますか?</dt>
  <dd>
    <ul class= "search-list">
      <li>
      <div class="yesno">
      <%= f.radio_button :drive_eq, true, id:'drive_ok', checked: true  %>
      <%= f.label :drive_true ,"はい", for: 'drive_ok', class:"switch-on" %>
      <%= f.radio_button :drive_eq, false, id:'drive_ng' %>
      <%= f.label :drive_false ,"いいえ",for: 'drive_ng', class:"switch-off" %>
      </div>

    <div class="yesno">
      <input type="radio" name="drive" id="drive-on" value="d-on" checked="">
      <label for="drive-on" class="switch-on">はい</label>
      <input type="radio" name="drive" id="drive-off" value="d-off">
      <label for="drive-off" class="switch-off">いいえ</label>
    </div>
      </li>
    </ul>
  </dd>

こちらの記載も似たような(?)記載が2つありますが、挙動させたいのはf.radio_buttonの方でしょうか?もしそうであれば、fform_with ... do |f|が定義されているでしょうか?

現状、何が起きているのか・どういう記載になっているのか・レンダリングされたHTMLは期待しているものになっているのかetcを考えながら仮説検証を行って試行錯誤してみましょう。

CarbazochromeT commented 1 year ago

説明が不十分で申し訳ございません。 今回作動させたいボタンは上のf.radio_buttonです。 今は検索機能フォームを作っている段階であり、まだデータベースへの反映は確認できておりません。

:driveがないという旨のエラーが出ているためボタンが見れない状態ではありますが、まだアクティブ時に色が変更しているところは確認できておりません。

下のコードのHTMLとcssはアクティブ時に色が変わることは確認済で、下のコードをf.radio_buttonへとコードを書き直している最中でございます。

Tsuchiya2 commented 1 year ago

複数の要素が混じっているようなので切り分けさせてください。

ます、fの方は問題ない状態なのでしょうか?共有されている情報からはform_withなどの記載が見られず、その問題はクリアになっているのかが読み取れなかったのですが、こちらは大丈夫でしょうか。

次に、上記がクリアという前提の話になりますが、ingredientsのbooleanのカラムが対象かと思われますが、ransackでアソシエーション先のカラムを対象にする際はどのようにすれば扱えるかを調べたり、仮説立て、検証、試行錯誤してみましょう。

CarbazochromeT commented 1 year ago
search.html.erb
      <%= f.radio_button :ingredients_drive_eq, true, id:'drive_ok', checked: true  %>
      <%= f.label :drive_true ,"はい", for: 'drive_ok', class:"switch-on" %>

このように設定したら動きました!ありがとうございます!