2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

たったひとりの個人開発Advent Calendar 2022

Day 5

Railsでselectと自由記述を両立させるフォームをつくる

Last updated at Posted at 2022-12-04

問題提起

 作成したアプリでは、日報を入力する際に作業のジャンルも併せて入力する。例えば「腹筋10回した!」というときはあらかじめ設定した「運動」というジャンル。「参考書20p進んだ」なら「勉強」など。

 ジャンルは予めユーザーが設定してそのあと選択肢にのってくるようにしていた。はじめは。

 でもそれって面倒くさい。

 「よし、日報書くぞ」
:ジャンル / 作業内容 / かかった時間
 > 勉強 / 参考書20p / 1H

「あ、そういえば個人開発もやったんだ」

:ジャンル / 作業内容 / かかった時間
 > 個人開発....
 「ジャンルつくってなかった。ジャンル画面に遷移して、
ジャンルを新規作成でつくって、また戻って」

 めんどうくさい。

自由記述/選択肢の共存

 要は通常は選択肢から選び、ないなら自由記述でつくることができればいいのだ。
選択肢を出すヘルパーはselect_tagが有名だ。しかし、自由記述をやるなら、datalistでつくろう。

 こんなかんじ。

app/views/reports/_form.html.erb
<!-- 略 -->
<div id="report_items">
    <%= f.fields_for :report_items do |item| %>
    <%= render "report_item_fields", f: item %>
  <% end %>
<!-- 略 -->          
</div>  

<!-- 略 -->

app/views/reports/_report_item_fields.erb
<!-- 略 -->
<%= f.text_field :genre_name ,{:class => 'form-control' ,:list => 'datalistOptions3', :id => 'exampleDataList3' , :value => get_genre_name(f.object.genre_id) } %>
    <datalist id="datalistOptions3">
    <% @select_genre.each do |genre| %>
    <option value= <%= genre.name %> >
<% end %>
<!--  -->

text_field のオプションとして:listを追加。直後にそれと紐づくidのdatalistを作成する。datalistの中身はコントローラーでとってきたインスタンスをループで回してやる。

app/controllers/reports_controller.rb
#略
  def new
    @report = Report.new
    @report.report_items.build
    @select_genre = Genre.where(user_id: current_user)
  end

 
 自由に記述した場合は、日報追加時のcreateアクションの時にジャンルを新規追加してやればいい。

app/controllers/reports_controller.rb
#略...
 def create
    para = report_genre_params[:report_items_attributes]
    report_lists = para.values
    report_lists.each do |report|
      genre_name = report[:genre_name]
      if genre_name.nil?
        report[:genre_id] = nil
        break
      end
      @genre_new = Genre.find_by(name:genre_name,user_id: current_user)
      if @genre_new.nil?
        @genre_new = Genre.new("name"=> genre_name, "user_id" => current_user.id)
        @genre_new.save
      end
      report[:genre_id] = @genre_new.id
    end
# 略
  private

  def report_genre_params
    params.require(:report).permit(:content, :reported_on, report_items_attributes: [:content, :genre_id, :genreset, :genre_name ,:work_hours, :content_for_share, :id])
  end

 そのようになった。

まとめ

 めんどうくさい、という動作を減らしてつかいやすいものをつくる。そうするとうまくいく気がするなにごとも。

 
 

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?