class UserSettingsController < ApplicationController def show return head :unauthorized unless current_user render json: current_setting.serializable_hash end def update return head :unauthorized unless current_user raw_attributes = request.request_parameters field_errors = validate_raw_attributes(raw_attributes) return render_validation_error fields: field_errors if field_errors.present? setting = current_setting setting.assign_attributes(raw_attributes.slice(*Setting::EDITABLE_ATTRIBUTES)) if setting.save render json: setting.serializable_hash, status: :ok else render_validation_error setting end end private def current_setting Setting.find_or_create_by!(user: current_user) do |setting| setting.assign_attributes(Setting.defaults) end rescue ActiveRecord::RecordNotUnique Setting.find_by!(user: current_user) end def validate_raw_attributes raw_attributes raw_attributes.each_with_object({ }) do |(key, value), errors| unless Setting::EDITABLE_ATTRIBUTES.include?(key) errors[key.to_sym] = ['不明な設定です.'] next end next if value_matches_type?(key, value) errors[key.to_sym] = ['値の型が不正です.'] end end def value_matches_type? key, value case Setting::TYPE_BY_ATTRIBUTE.fetch(key) when :string value.is_a?(String) when :integer value.is_a?(Integer) when :boolean value == true || value == false else false end end end