在 Rails API 中实现表视图显示用户设置,通常涉及以下几个核心概念:
# 生成模型
rails g model UserSetting user:references theme:string notifications_enabled:boolean language:string
rails db:migrate
# 控制器
# app/controllers/user_settings_controller.rb
class UserSettingsController < ApplicationController
before_action :authenticate_user!
def index
@settings = current_user.user_setting || current_user.create_user_setting
render json: @settings
end
def update
@settings = current_user.user_setting || current_user.create_user_setting
if @settings.update(user_setting_params)
render json: @settings
else
render json: @settings.errors, status: :unprocessable_entity
end
end
private
def user_setting_params
params.require(:user_setting).permit(:theme, :notifications_enabled, :language)
end
end
# config/routes.rb
resources :user_settings, only: [:index, :update]
import React, { useState, useEffect } from 'react';
import axios from 'axios';
const UserSettingsTable = () => {
const [settings, setSettings] = useState({
theme: 'light',
notifications_enabled: true,
language: 'en'
});
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchSettings = async () => {
try {
const response = await axios.get('/user_settings', {
headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` }
});
setSettings(response.data);
setLoading(false);
} catch (err) {
setError(err.message);
setLoading(false);
}
};
fetchSettings();
}, []);
const handleChange = (e) => {
const { name, value, type, checked } = e.target;
setSettings(prev => ({
...prev,
[name]: type === 'checkbox' ? checked : value
}));
};
const handleSubmit = async (e) => {
e.preventDefault();
try {
await axios.put('/user_settings', { user_setting: settings }, {
headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` }
});
alert('Settings updated successfully!');
} catch (err) {
setError(err.message);
}
};
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
return (
<form onSubmit={handleSubmit}>
<table>
<thead>
<tr>
<th>Setting</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>Theme</td>
<td>
<select name="theme" value={settings.theme} onChange={handleChange}>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</td>
</tr>
<tr>
<td>Notifications</td>
<td>
<input
type="checkbox"
name="notifications_enabled"
checked={settings.notifications_enabled}
onChange={handleChange}
/>
</td>
</tr>
<tr>
<td>Language</td>
<td>
<select name="language" value={settings.language} onChange={handleChange}>
<option value="en">English</option>
<option value="es">Spanish</option>
<option value="fr">French</option>
</select>
</td>
</tr>
</tbody>
</table>
<button type="submit">Save Settings</button>
</form>
);
};
export default UserSettingsTable;
原因:前端应用与 API 不在同一域名下,浏览器安全策略阻止请求
解决方案: 在 Rails 中启用 CORS:
# Gemfile
gem 'rack-cors'
# config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*' # 生产环境应替换为具体域名
resource '*',
headers: :any,
methods: [:get, :post, :put, :patch, :delete, :options, :head]
end
end
原因:用户首次访问时可能没有设置记录
解决方案:
在控制器中使用 ||
运算符或 find_or_create_by
方法确保设置存在:
@settings = current_user.user_setting || current_user.create_user_setting
# 或
@settings = UserSetting.find_or_create_by(user_id: current_user.id)
原因:设置项过多导致渲染缓慢
解决方案:
没有搜到相关的文章