Sails.js创建新记录报错及Model参数自定义验证问题咨询
Hey there! Let's break down and fix your two Sails.js issues step by step:
1. Fixing TypeError: User.create(...).fetch is not a function
The error pops up because in Sails.js v1 and later versions, the .fetch() method is no longer needed for Model.create()—it automatically returns the newly created record when the promise resolves. Also, mixing async/await with .then/.catch makes your code harder to follow, so let's clean that up:
Here’s the corrected controller code:
async function(req, res, next) { try { // Create the user and get the new record directly const new_user = await User.create({ username: req.param('username'), // ⚠️ Critical note: Storing plain-text passwords is extremely unsafe! // Use bcrypt to hash passwords instead (example included) password: await sails.helpers.bcrypt.hash('654654'), type: 1, }); return res.ok({ user: new_user }); } catch (err) { console.log(err); return res.serverError({ err: err.message }); } }
- Removed the unnecessary
.fetch()call (it’s obsolete in modern Sails versions) - Switched to
try/catchto handle errors consistently withasync/await - Added a reminder about password hashing (never store plain-text passwords in production!)
2. Adding Parameter Validation & Custom Error Messages
Sails.js has built-in validation tools you can leverage directly in your model. Here’s how to set it up:
Step 1: Define Validation Rules in Your User Model (api/models/User.js)
module.exports = { attributes: { username: { type: 'string', required: true, // Mark as mandatory unique: true, // Ensure username is unique across records minLength: 3, // Minimum 3 characters maxLength: 20, // Maximum 20 characters }, password: { type: 'string', required: true, minLength: 6, // Password must be at least 6 characters }, type: { type: 'number', isIn: [1, 2], // Only allow values 1 or 2 } }, // Customize error messages for each validation rule customMessages: { required: { username: 'Username cannot be empty', password: 'Password is required' }, unique: { username: 'This username is already taken' }, minLength: { username: 'Username must be at least 3 characters long', password: 'Password must be at least 6 characters long' }, maxLength: { username: 'Username cannot exceed 20 characters' }, isIn: { type: 'User type can only be 1 or 2' } }, // Optional: Add custom validation logic with a beforeCreate hook beforeCreate: async function(values, proceed) { // Example: Block usernames with special characters const validUsernameRegex = /^[a-zA-Z0-9_]+$/; if (!validUsernameRegex.test(values.username)) { return proceed(new Error('Username can only contain letters, numbers, and underscores')); } return proceed(); } };
Step 2: Handle Validation Errors in Your Controller
When validation fails, Sails throws an error with an invalidAttributes property that contains all failed rules and your custom messages. Format these to send friendly responses:
async function(req, res, next) { try { const new_user = await User.create({ username: req.param('username'), password: await sails.helpers.bcrypt.hash(req.param('password')), type: req.param('type'), }); return res.ok({ user: new_user }); } catch (err) { // Check if it's a validation error if (err.invalidAttributes) { const formattedErrors = {}; // Extract the first error message for each field Object.keys(err.invalidAttributes).forEach(field => { formattedErrors[field] = err.invalidAttributes[field][0].message; }); return res.badRequest({ errors: formattedErrors }); } // Handle other server errors console.log(err); return res.serverError({ err: err.message }); } }
内容的提问来源于stack exchange,提问作者mas cm

