Flatiron Phase 4: Full-Stack

Phil Sheridan
3 min readSep 24, 2024

--

Phase 4 of Flatiron was dense and covered a wide range of topics that opened my eyes to the nature of full-stack development. I found myself drowning in new words, trying to understand new tools, and desperately needing to review. After getting a grip on the content of this phase, I loved how cohesively everything came together. Writing code in Python and JavaScript back-to-back has become much more natural than earlier in the course, and I found I was easily picking up new workflows, and repeatedly iterating.

The most difficult part of this phase for me was understanding the bridge between SQLAlchemy models and React fetch requests. It wasn’t until I started building my final project that everything started to click, and I was able to add, or change my models and their corresponding requests. That being said- nothing is fluent, and the language used for these relationships is still often difficult to grasp. The more complex my projects become, the more I understand that coding in full stack requires attention, or at the very least detailed notes.

My final project for Phase 4 of Flatiron is called DayList. The main files I want to focus on are models.py, app.py, and specific fetch requests from any .js file. The models file contains the skeletons of all the objects used in the app: user, calendar, note, and user_calendar. Each of these models contain relationships to each other: calendars have notes, users have calendars, etc. I struggled to understand how to initialize these relationships for a long time and came to understand that there are multiple ways of creating them.

Because calendars in my app can be shared between users, I needed to create a many-to-many relationship between users and calendars.

class User_Calendar(db.Model, SerializerMixin):
__tablename__ = 'user_calendars'
serialize_rules = ('-user.calendars', '-calendar.users')

user_id = db.Column(db.Integer, db.ForeignKey('users.id'), primary_key=True)
calendar_id = db.Column(db.Integer, db.ForeignKey('calendars.id'), primary_key=True)
permission = db.Column(db.String, nullable=False)

user = db.relationship('User', back_populates='calendars')
calendar = db.relationship('Calendar', back_populates='users')

def __repr__(self):
return f'<User_Calendar {self.calendar_id}>'

Above is the User_Calendar model used to bridge the user and calendar models together. This table has two primary keys, both of which are required making it a “join-table”. When a calendar is created, itself and the current user are added to a new User_Calendar (by default, the user is set as an owner). When a calendar is shared, a new User_Calendar is created with the existing calendar_id and user_id. By setting the cascade property to of the relationships associated with the Calendar model to cascade=`all, delete-orphan`, the calendar will delete any Notes, or User_Calendars associated with itself on deletion.

After finally completing my models, I found that interacting with them was extremely intuitive. Multiple times, I needed to change or add an attribute of a model and was easily able to add it and upgrade my database to match. Flask RESTful methods were easy to create and allowed me to customize what was returned by the request easily. Similarly to building models, the User_Calendar methods were slightly confusing before fully understood the logic behind them:

    def get(self, calendarID):
shared_user_ids = []
shared_users = []

user_calendars = User_Calendar.query.filter(User_Calendar.calendar_id==calendarID).all()
for relationship in user_calendars:
shared_user_ids.append(relationship.user_id)

for user_id in shared_user_ids:
this_username = User.query.filter(User.id == user_id).first().username
this_permission = User_Calendar.query.filter(
User_Calendar.user_id == user_id and
User_Calendar.calendar_id == calendarID).first().permission

shared_users.append(this_username + ": " + this_permission)
return shared_users, 200

In the code above, I specifically wanted to retrieve a string of the username, and permission level of a user to a calendar. To do this, I found all the User_Calendars associated with a given calendar and created a list of those User_Calendar user_ids. Using these user_id’s, I was able to find the username of the user, and permission level of the user through two more queries. I returned the agglutinated strings in a list called shared_users. This list is displayed when the user opens the sharing menu of a calendar.

Like each phase of Flatiron School, this phase has opened my eyes to so many new possibilities. I am at a point in my journey where I feel confident in creating almost anything I could think up. Through lulls of imposter syndrome, I am extremely proud of what I have learned and am excited to finish off the next phase and to build a portfolio.

--

--

Phil Sheridan
Phil Sheridan

No responses yet