Conversation
| class Goal(db.Model): | ||
| goal_id = db.Column(db.Integer, primary_key=True) | ||
| goal_id = db.Column(db.Integer, primary_key=True, autoincrement=True) | ||
| title = db.Column(db.String) | ||
| tasks = db.relationship("Task", back_populates="goal", lazy=True) |
There was a problem hiding this comment.
Great job completing Task List Abby! Your code looks clean and easily readable. I want to point out the good variable naming and your code is DRY. Great use of helper methods in your models! Excellent work using blue prints & creating RESTful CRUD routes for each model.
| def from_dict(cls, goal_data): | ||
| new_goal = Goal( | ||
| title=goal_data["title"] | ||
| ) | ||
|
|
||
| return new_goal |
There was a problem hiding this comment.
I noticed you created this class method but didn't make use of it
| class Task(db.Model): | ||
| task_id = db.Column(db.Integer, primary_key=True) | ||
| task_id = db.Column(db.Integer, primary_key=True, autoincrement=True) | ||
| title = db.Column(db.String) #when refactoring change to varchar | ||
| description = db.Column(db.String) # when refacoring change to varvhar | ||
| completed_at = db.Column(db.DateTime, default=None, nullable=True) | ||
| goal_id = db.Column(db.Integer, db.ForeignKey('goal.goal_id')) | ||
| goal = db.relationship("Goal", back_populates="tasks") |
There was a problem hiding this comment.
Nice approach creating this relationship to your Goal model. Why not use lazy here?
| def from_dict(cls, task_data): | ||
| new_task = Task( | ||
| title=task_data["title"], | ||
| description=task_data["description"], | ||
| completed_at=task_data["completed_at"] | ||
| ) | ||
|
|
||
| return new_task |
There was a problem hiding this comment.
I noticed you created this class method but didn't make use of it
| "id":self.task_id, | ||
| "title":self.title, | ||
| "description":self.description, | ||
| "is_complete": True if self.completed_at else False}} |
| from .routes import task_list_bp | ||
| app.register_blueprint(task_list_bp) | ||
| from .routes import goals_bp | ||
| app.register_blueprint(goals_bp) |
There was a problem hiding this comment.
Great work registering these blueprints ✅
| if test_config is None: | ||
| app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get( | ||
| "SQLALCHEMY_DATABASE_URI") | ||
| app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get("RENDER_DB_URI") |
| @@ -30,5 +32,9 @@ def create_app(test_config=None): | |||
| migrate.init_app(app, db) | |||
There was a problem hiding this comment.
Great job! We need to pass our instance of our app & the instance of our SQLALchemy db to connect the db and migrate to our Flask app
| from datetime import datetime | ||
| import requests | ||
| import json | ||
| from dotenv import load_dotenv |
There was a problem hiding this comment.
Great work! We need to import load_dotenv to set up environment variables in our .env file
| from app import db | ||
| from app.models.task import Task | ||
| from app.models.goal import Goal | ||
| from flask import Blueprint, jsonify, make_response, request, abort |
There was a problem hiding this comment.
👍🏾 These imports help a great deal when it comes to our request & response cycle
| def validate_task(task_id): | ||
| try: | ||
| task_id = int(task_id) | ||
| except: | ||
| abort(make_response({"message": f"Task {task_id} invalid"}, 400)) | ||
| task = Task.query.get(task_id) | ||
| if not task: | ||
| abort(make_response({"details": "Invalid Data"}, 404)) | ||
| return task |
There was a problem hiding this comment.
Nice approach to handling an invalid task 😁
| def validate_goal(goal_id): | ||
| try: | ||
| goal_id = int(goal_id) | ||
| except: | ||
| abort(make_response({"message": f"Goal {goal_id} invalid"}, 400)) | ||
| goal = Goal.query.get(goal_id) | ||
| if not goal: | ||
| abort(make_response({"details": "Invalid Data"}, 404)) | ||
| return goal |
There was a problem hiding this comment.
Nice approach to handling an invalid goal 😁 There's a bunch of repeated code here, any ideas of how to refactor?
| new_task = Task( | ||
| title = request_body["title"], | ||
| description = request_body["description"], | ||
| # completed_at = request_body["completed_at"] |
There was a problem hiding this comment.
It’s good practice to avoid committing commented out code when submitting a PR.
| db.session.add(new_task) | ||
| db.session.commit() |
There was a problem hiding this comment.
Great job using db.session.<method-name>. Session gives us access to the follow:
dbis our app’s instance of SQLAlchemy.sessionrepresents our active database connection.- By referencing
db.sessionwe can use SQLAlchemy’s methods to perform tasks like:- committing a change to a model
- storing a new record of a model
- deleting a record.
- By referencing
db.session.add()you are able to use the SQLAlchemy method to store a new record of the task model
| def update_task_to_complete(task_id): | ||
| task = validate_task(task_id) | ||
| task.completed_at = datetime.now() | ||
| #slack implementation | ||
| url = "https://slack.com/api/chat.postMessage" | ||
| payload = json.dumps({ | ||
| "channel": "C0581AUJACV", | ||
| "text": (f"Someone just completed the task {task.title}") | ||
| }) | ||
| headers = { | ||
| 'Authorization': os.environ.get("SLACK_API_TOKEN"), | ||
| 'Content-Type': 'application/json' | ||
| } | ||
| response = requests.request("POST", url, headers=headers, data=payload) | ||
| print(response.text) | ||
| db.session.commit() | ||
| return task.to_dict(), 200 |
There was a problem hiding this comment.
This function is pretty packed, for readability I suggest using more spacing in between lines. Something like this:
def update_task_to_complete(task_id):
task = validate_task(task_id)
task.completed_at = datetime.now()
#slack implementation
url = "https://slack.com/api/chat.postMessage"
payload = json.dumps({
"channel": "C0581AUJACV",
"text": (f"Someone just completed the task {task.title}")
})
headers = {
'Authorization': os.environ.get("SLACK_API_TOKEN"),
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
db.session.commit()
return task.to_dict(), 200
No description provided.