Rails での FullCalendar の実装
概要
RoR プロジェクトに FullCalendar を実装していますが、行を更新しようとすると次のエラーが発生しました。
イベントをクリックしたときに行を更新するための Ajax 呼び出しは次のとおりです。
$.ajax({
type: 'PATCH', // Use PATCH or PUT depending on your Rails routes
url: '/events/' + eventId, // Adjust the URL to your Rails route
data: {
event: {
title: 'updatedTitle',
start_date: 'updatedStartDate',
end_date: 'updatedEndDate',
description: 'updatedDescription'
}
},
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
},
success: function(response) {
if (response.status === 'success') {
// Update the event data in FullCalendar
arg.event.setProp('title', updatedTitle);
arg.event.setStart(updatedStartDate);
arg.event.setEnd(updatedEndDate);
arg.event.setExtendedProp('description', updatedDescription);
// Close the modal
$('#eventModal').modal('hide');
// Display a success message (you can use Swal or other methods)
Swal.fire({
text: 'Event updated successfully',
icon: 'success',
buttonsStyling: false,
confirmButtonText: 'Ok, got it!',
customClass: {
confirmButton: 'btn btn-primary',
}
});
} else {
// Handle the case where the update failed
Swal.fire({
text: 'Event update failed: ' + response.message,
icon: 'error',
buttonsStyling: false,
confirmButtonText: 'Ok, got it!',
customClass: {
confirmButton: 'btn btn-primary',
}
});
}
},
error: function(error) {
console.log('AJAX request to Rails failed.');
console.log(error)
},
});
イベント ID を console.log に記録しましたが、正しく実装されています (値は 76)。 Ajax 呼び出しで使用される URL が URL: ‘/events/’ である理由がわかりません。
これが私のroutes.rbファイルです。
Rails.application.routes.draw do
resources :telephones
get 'home/index'
resources :tickets
resources :imprimantes
resources :voitures
resources :telephones
resources :events
resources :events do
collection do
post 'import_ics'
get 'export_ics'
end
end
# Define a route for updating events using PATCH
patch '/events/:id', to: 'events#update', as: 'update_event'
resources :google_calendar, only: [:index, :create, :update, :destroy]
root 'home#index'
# Defines the root path route ("/")
# root "posts#index"
end
そして更新機能:
def update
@event = Event.find(params[:id])
if @event.update(event_params)
redirect_to events_path
else
render 'edit'
end
def event_params
params.require(:event).permit(:title, :start_date, :end_date, :description)
end
end
私は何を取りこぼしたか ?
編集:Railsコンソールログ
Started PATCH "/events/68" for 127.0.0.1 at 2023-11-14 23:55:04 +0100
Processing by EventsController#update as */*
Parameters: {"event"=>{"title"=>"updatedTitle", "start_date"=>"updatedStartDate", "end_date"=>"updatedEndDate", "description"=>"updatedDescription"}, "id"=>"68"}
Event Load (0.5ms) SELECT `events`.* FROM `events` WHERE `events`.`id` = 68 LIMIT 1
↳ app/controllers/events_controller.rb:42:in `update'
TRANSACTION (15.7ms) BEGIN
↳ app/controllers/events_controller.rb:43:in `update'
Event Update (11.3ms) UPDATE `events` SET `events`.`title` = 'updatedTitle', `events`.`start_date` = NULL, `events`.`end_date` = NULL, `events`.`description` = 'updatedDescription', `events`.`updated_at` = '2023-11-14 22:55:04.903524' WHERE `events`.`id` = 68
↳ app/controllers/events_controller.rb:43:in `update'
TRANSACTION (8.0ms) COMMIT
↳ app/controllers/events_controller.rb:43:in `update'
Redirected to http://127.0.0.1:3000/events
Completed 302 Found in 61ms (ActiveRecord: 35.5ms | Allocations: 4141)
Started PATCH "/events" for 127.0.0.1 at 2023-11-14 23:55:04 +0100
ActionController::RoutingError (No route matches [PATCH] "/events"):
解決策
Rails ログによると、JS が有効なリクエストを発行し、レコードを更新しているようです。問題は、更新が成功するとコントローラーで events_path にリダイレクトされるということです
if @event.update(event_params)
redirect_to events_path
else
render 'edit'
end
リクエストの MIME タイプを区別するロジックを追加してみてはいかがでしょうか?
何かのようなもの:
def update
@event = Event.find(params[:id])
respond_to do |format|
if @event.update(event_params)
format.html { redirect_to events_path }
format.json { render json: { status: :success } }
else
format.html { render 'edit' }
format.json { render json: { status: :unprocessable_entity } }
end
end
end
ソースへのリンク Mime が応答する
また、ajax 呼び出しに Accept ヘッダーを追加する必要があります。 ajax 呼び出しは次のようになります。
$.ajax({
type: 'PATCH',
url: '/events/1',
headers: {
Accept: "application/json"
},
data: {
event: {
title: 'new_title'
}
},
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
},
success: function(response) {
console.log(response)
// Handle your response
},
error: function(response) {
console.error(response)
// Handle your error
}
})