diff --git a/controllers/categories.js b/controllers/categories.js new file mode 100644 index 00000000..c09cd712 --- /dev/null +++ b/controllers/categories.js @@ -0,0 +1,32 @@ +let express = require('express') +let db = require('../models') +let router = express.Router() + +// GET /categories -- show all the categories that exist +router.get('/', (req, res) => { + db.category.findAll() + .then((category) => { + res.render('categories/index', { categories: category }) + }) + .catch((err) => { + res.status(400).render('main/404') + }) +}) + + +// GET /categories/:id -- show a speicifc category and all the projects with that category +router.get('/:id', (req, res) => { + db.category.findOne({ + where: { id: req.params.id }, + include: [{ model: db.project}] + }) + .then((category) => { + if (!category) throw Error() + res.render('categories/show', { category: category }) + }) + .catch((err) => { + res.status(400).render('main/404') + }) +}) + +module.exports = router \ No newline at end of file diff --git a/controllers/projects.js b/controllers/projects.js index 3d878a8a..11b2e054 100644 --- a/controllers/projects.js +++ b/controllers/projects.js @@ -11,6 +11,12 @@ router.post('/', (req, res) => { description: req.body.description }) .then((project) => { + const [category] = db.category.findOrCreate({ + where: { + name: req.body.category + } + }) + project.addCategory(category) res.redirect('/') }) .catch((error) => { diff --git a/dbTest.js b/dbTest.js new file mode 100644 index 00000000..33592c19 --- /dev/null +++ b/dbTest.js @@ -0,0 +1,51 @@ +const db = require('./models') + +// db.category.create({ +// name: 'node' +// }) +// .then(category => { +// console.log(category.id) +// }) +// .catch(console.log) + +// async function createCategory() { +// try { +// const newCategory = await db.category.create({ name: 'python' }) +// console.log(newCategory) +// } catch (err) { +// console.log(err) +// } +// } + +// createCategory() + +// db.project.findOne({ +// where: { id: 1 }, +// include: [db.category] +// }) +// .then(project => { +// // by using eager loading, the project model should have a categories key +// console.log(project.categories) + +// // createCategory function should be available to this model - it will create the category then add it to the project +// project.createCategory({ name: 'express' }) +// .then(category => { +// console.log(category.id) +// }) +// }) +// const db = require('./models') + +// db.category.findOne({ +// where: { id: categoryId }, +// include: [db.project] +// }) +// .then(category => { +// console.log(category.Projects) +// // }) +// db.category.findOne({ +// where: { id: 1 }, +// include: [db.project] +// }) +// .then(category => { +// console.log(category.projects) +// }) \ No newline at end of file diff --git a/index.js b/index.js index f404f83d..e9753548 100644 --- a/index.js +++ b/index.js @@ -24,6 +24,7 @@ app.get('/', (req, res) => { }) app.use('/projects', require('./controllers/projects')) +app.use('/categories', require('./controllers/categories')) app.get('*', (req, res) => { res.render('main/404') diff --git a/migrations/20230405223135-create-category.js b/migrations/20230405223135-create-category.js new file mode 100644 index 00000000..8e52fd79 --- /dev/null +++ b/migrations/20230405223135-create-category.js @@ -0,0 +1,28 @@ +'use strict'; +/** @type {import('sequelize-cli').Migration} */ +module.exports = { + async up(queryInterface, Sequelize) { + await queryInterface.createTable('categories', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + name: { + type: Sequelize.STRING + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + }, + async down(queryInterface, Sequelize) { + await queryInterface.dropTable('categories'); + } +}; \ No newline at end of file diff --git a/migrations/20230405224412-create-categories-projects.js b/migrations/20230405224412-create-categories-projects.js new file mode 100644 index 00000000..4e407a24 --- /dev/null +++ b/migrations/20230405224412-create-categories-projects.js @@ -0,0 +1,31 @@ +'use strict'; +/** @type {import('sequelize-cli').Migration} */ +module.exports = { + async up(queryInterface, Sequelize) { + await queryInterface.createTable('categoriesProjects', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + categoryId: { + type: Sequelize.INTEGER + }, + projectId: { + type: Sequelize.INTEGER + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + }, + async down(queryInterface, Sequelize) { + await queryInterface.dropTable('categoriesProjects'); + } +}; \ No newline at end of file diff --git a/models/categoriesprojects.js b/models/categoriesprojects.js new file mode 100644 index 00000000..ddb47da2 --- /dev/null +++ b/models/categoriesprojects.js @@ -0,0 +1,24 @@ +'use strict'; +const { + Model +} = require('sequelize'); +module.exports = (sequelize, DataTypes) => { + class categoriesProjects extends Model { + /** + * Helper method for defining associations. + * This method is not a part of Sequelize lifecycle. + * The `models/index` file will call this method automatically. + */ + static associate(models) { + // define association here + } + } + categoriesProjects.init({ + categoryId: DataTypes.INTEGER, + projectId: DataTypes.INTEGER + }, { + sequelize, + modelName: 'categoriesProjects', + }); + return categoriesProjects; +}; \ No newline at end of file diff --git a/models/category.js b/models/category.js new file mode 100644 index 00000000..045e7c1e --- /dev/null +++ b/models/category.js @@ -0,0 +1,24 @@ +'use strict'; +const { + Model +} = require('sequelize'); +module.exports = (sequelize, DataTypes) => { + class category extends Model { + /** + * Helper method for defining associations. + * This method is not a part of Sequelize lifecycle. + * The `models/index` file will call this method automatically. + */ + static associate(models) { + // define association here + models.category.belongsToMany(models.project, { through: 'categoriesProjects'} ) + } + } + category.init({ + name: DataTypes.STRING + }, { + sequelize, + modelName: 'category', + }); + return category; +}; \ No newline at end of file diff --git a/models/project.js b/models/project.js index 735a0a47..6fd14270 100644 --- a/models/project.js +++ b/models/project.js @@ -11,6 +11,8 @@ module.exports = (sequelize, DataTypes) => { */ static associate(models) { // define association here + models.project.belongsToMany(models.category, { through: 'categoriesProjects'} ) + } } project.init({ diff --git a/scratchpad.txt b/scratchpad.txt new file mode 100644 index 00000000..aa2e3cfc --- /dev/null +++ b/scratchpad.txt @@ -0,0 +1,8 @@ +sequelize model:create --name category --attributes name:string + +categoriesProjects => categoriesProjects model +------------------------ +categoryId: FK REFERENCES category.id (integer) +projectId: FK REFERENCES project.id (integer) + +sequelize model:create --name categoriesProjects --attributes categoryId:integer,projectId:integer \ No newline at end of file diff --git a/views/categories/show.ejs b/views/categories/show.ejs new file mode 100644 index 00000000..9f4b0fd5 --- /dev/null +++ b/views/categories/show.ejs @@ -0,0 +1,9 @@ +

Project Categories

+ +<% categories.forEach(category => { %> +

<%= category.name %>

+ <% projects.forEach(project => { %> +

<%= project.name %>

+ <% }) %> +<% }) %> + diff --git a/views/projects/new.ejs b/views/projects/new.ejs index 3342d3ee..277c9b5e 100644 --- a/views/projects/new.ejs +++ b/views/projects/new.ejs @@ -16,6 +16,11 @@ +
+ + +
+