fukasawamoe / yoriyoi

1 stars 0 forks source link

スケジュールの編集 #8

Closed fukasawamoe closed 11 months ago

fukasawamoe commented 11 months ago
#models

#schedule.rb
class Schedule < ApplicationRecord
  belongs_to :user
  has_many :tasks, inverse_of: :schedule
  accepts_nested_attributes_for :tasks, reject_if: :all_blank, allow_destroy: true

  validates :name, presence: true,  length: { maximum: 255 }
  validates :day_of_week, presence: true
  validate :unique_day_of_week_per_user

  private

  def unique_day_of_week_per_user
    # ユーザーが作成したすべてのスケジュールの曜日を取得
    existing_days = user.schedules.where.not(id: id).pluck(:day_of_week).flatten
    # 新しく作成または更新しようとしているスケジュールの曜日
    new_days = day_of_week
    # 既存のスケジュールと新しいスケジュールで重複する曜日があるか確認
    if (existing_days & new_days).any?
      errors.add(:day_of_week, '各曜日につき一つだけスケジュールを作成できます')
    end
  end
end

#task.rb
class Task < ApplicationRecord
  belongs_to :schedule

  validates :task_time, presence: true
  validates :to_do, presence: true

end
#controllers
class SchedulesController < ApplicationController
    def create
        params[:schedule][:tasks_attributes].each do |_, task_attributes|
          if task_attributes["task_time(4i)"].blank? && task_attributes["task_time(5i)"].blank?
            task_attributes.delete("task_time(1i)")
            task_attributes.delete("task_time(2i)")
            task_attributes.delete("task_time(3i)")
          else
            year = task_attributes["task_time(1i)"].to_i
            month = task_attributes["task_time(2i)"].to_i
            day = task_attributes["task_time(3i)"].to_i
            hour = task_attributes["task_time(4i)"].to_i
            minute = task_attributes["task_time(5i)"].to_i

            task_time = Time.zone.local(year, month, day, hour, minute)
          end
        end

        @schedule = current_user.schedules.build(schedule_params)

        if @schedule.save
          redirect_to schedule_path(@schedule), notice: 'スケジュールが作成されました。'
        else
          render :new, status: :unprocessable_entity
        end
      end

    def update
    params[:schedule][:tasks_attributes].each do |_, task_attributes|
      if task_attributes["task_time(4i)"].blank? && task_attributes["task_time(5i)"].blank?
        task_attributes.delete("task_time(1i)")
        task_attributes.delete("task_time(2i)")
        task_attributes.delete("task_time(3i)")
      end
    end

    if @schedule.update(schedule_params)
      redirect_to schedule_path(@schedule)
    else
      render :edit
    end
  end
#views
#_form.html.erb
<main class="w-full flex justify-center">
  <%= form_with(model: schedule, local: true) do |f| %>
    <%= render 'shared/error_messages', object: f.object %>
    <div class="form-container rounded">
      <div class="field p-8">
        <%= f.text_field :name, placeholder: "スケジュール名", class: 'rounded' %>
        <% ['日', '月', '火', '水', '木', '金', '土'].each_with_index do |day, index| %>
          <%= check_box_tag 'schedule[day_of_week][]', index, schedule.day_of_week.include?(index), class: 'rounded' %>
          <%= day %>
        <% end %>
        <%= button_tag 'すべてに適用する', type: 'button', id: 'select-all', class: 'rounded' %>
        <%= button_tag 'すべて解除する', type: 'button', id: 'deselect-all', class: 'rounded' %>
      </div>
      <div class="form-group">
        <%= f.fields_for :tasks do |task| %>

          <%= render 'task_fields', f: task %>

        <% end %>
        <div class="flex justify-center p-8">
          <%= link_to_add_association '追加', f, :tasks, class:"btn btn-accent" %>
        </div>
      </div>
    </div>

    <div class="flex justify-center p-8">
      <button class="btn btn-accent" type="submit">スケジュールを保存する</button>
    </div>
  <% end %>
  <script>
    document.getElementById('select-all').addEventListener('click', function() {
      var checkboxes = document.querySelectorAll('input[type=checkbox]');
      for (var i = 0; i < checkboxes.length; i++) {
        if (checkboxes[i].id != 'schedule_tasks_attributes_0_goal_select') {
          checkboxes[i].checked = true;
        }
      }
    });
    document.getElementById('deselect-all').addEventListener('click', function() {
      var checkboxes = document.querySelectorAll('input[type=checkbox]');
      for (var i = 0; i < checkboxes.length; i++) {
        if (checkboxes[i].id != 'schedule_tasks_attributes_0_goal_select') {
          checkboxes[i].checked = false;
        }
      }
    });
  </script>

</main>

#_task_fields.html.erb
<div class="nested-fields">

  <div class="form-group flex justify-center items-center p-1">
    <%= f.time_select :task_time, { minute_step: 15, include_blank: true }, class:'rounded' %>
    <%= f.text_field :to_do, placeholder: "タスク", class: 'rounded' %>
    <%= f.text_field :memo, placeholder: "メモ", class: 'rounded' %>
    <%= link_to_remove_association "削除", f, class: "btn btn-accent" %>
  </div>

</div>
#config
#application.rb
module Yoriyoi
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 7.0
    # i18n
    config.i18n.default_locale = :ja
    config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.yml').to_s]

    #time_zone
    config.time_zone = 'Asia/Tokyo'
    # Configuration for the application, engines, and railties goes here.
    #
    # These settings can be overridden in specific environments using the files
    # in config/environments, which are processed later.
    #
    # config.time_zone = "Central Time (US & Canada)"
    # config.eager_load_paths << Rails.root.join("extras")

    # Don't generate system test files.
    config.generators.system_tests = nil
  end
end

pythonで19分時間がズレるという記事がありましたが、Railsでは記事がでませんでした https://qiita.com/suzuki-navi/items/9ed7670aa4a93cf021d2

デバッグで確認すると@schedule.saveの前後で書き変わってしまっているようです save前は以下のようになります [3] pry(#)> @schedule.tasks => [#<Task:0x0000000106d91ff0 id: nil, schedule_id: nil, task_time: Mon, 01 Jan 0001 00:00:00.000000000 LMT +09:18, to_do: "月曜日", memo: "", goal_select: false, created_at: nil, updated_at: nil>]

save後は以下のようになりました [1] pry(#)> @schedule.tasks Task Load (0.4ms) SELECT "tasks".* FROM "tasks" WHERE "tasks"."schedule_id" = $1 [["schedule_id", 41]] ↳ app/controllers/schedules_controller.rb:34:in `create' => [#<Task:0x0000000106f9af18 id: 83, schedule_id: 41, task_time: Sat, 01 Jan 2000 23:41:01.000000000 JST +09:00, to_do: "月曜日", memo: "", goal_select: false, created_at: Mon, 25 Sep 2023 19:23:21.732369000 JST +09:00, updated_at: Mon, 25 Sep 2023 19:23:21.732369000 JST +09:00>] [2] pry(#)>