Steak Whizard

The Philly Cheesesteak. Whether you love it or hate it, you likely have heard the never-ending debate about which is the best.

Enter Steak Whizard – a web application solely dedicated to finding the best steak in Philly. Review, rate, and let’s settl…


This content originally appeared on DEV Community and was authored by Michael Lobman

The Philly Cheesesteak. Whether you love it or hate it, you likely have heard the never-ending debate about which is the best.

Enter Steak Whizard - a web application solely dedicated to finding the best steak in Philly. Review, rate, and let's settle the debate.

The application is built with a React frontend (and the much appreciated help of the Bootstrap library) and a Ruby on Rails back end with a PostgreSQL database. It is hosted on Heroku.

There are three distinct Rails models that are mapped to tables in the database - User, Steak, Review. The Review table is the join table, belonging to one instance of User and one instance of Steak:

class Review < ApplicationRecord
    validates :rating, presence: true, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 10 }
    validates :toppings, presence: true
    validates :title, presence: true

    belongs_to :user
    belongs_to :steak
end

A User has many Reviews and many Steaks through Reviews:

class User < ApplicationRecord
    validates :username, presence: true, uniqueness: true
    validates :fav_steak, presence: true

    has_many :reviews
    has_many :steaks, through: :reviews
end

A Steak has many Reviews and many Users through Reviews:

class Steak < ApplicationRecord
    validates :restaurant, presence: true, uniqueness: true

    has_many :reviews
    has_many :users, through: :reviews
end

The models also use Active Record Validations to ensure that valid data is being saved in the database.

The site will ask the user to create an account with a username and password. Passwords are salted and hashed with BCrypt and securely stored in the database.

When the user successfully creates an account with a unique username, a session is created with the user's specific id inside the Users Controller:

def create
    user = User.create!(user_params)
    session[:user_id] = user.id
    render json: user, status: :created
end

Inside the Application Controller, the private authorize method locates the current user by the :user_id held in session and assigns it to the instance variable @current_user, rendering an error response unless the variable is truthy - that is, the user exists:

before_action :authorize

private

def authorize
    @current_user = User.find_by(id: session[:user_id])
    render json: { error: ["Not authorized"] }, status: :unauthorized unless @current_user
end

Note the before_action filter which is a method that runs before a controller action. As the other controllers inherit from Application Controller, this will ensure that the user is authorized to view the content which they have requested.

The application has four pages served by client-side routing - Home, Best Steak, My Reviews, and Add Steak.

Home acts as the landing page, rendering each instance of the Steak class as a card component. The card contains "Favorite" and "Review" buttons, conditionally rendered dependent on the user's reviews and favorite steak:
Home Page with Steak Cards
On the back end, when a user reviews a steak, the POST request points to the create method in the Reviews Controller:

class ReviewsController < ApplicationController

    def create
        review = @current_user.reviews.create!(review_params)
        steak = Steak.find(params[:steak_id])
        steak.update(rating: steak.calc_avg_rating)
        render json: @current_user, status: :created
    end

    private

    def review_params
        params.permit(:steak_id, :title, :comment, :rating, :toppings)
    end
end

The method creates a new instance of the Review class that will be associated with the user stored in the @current_user variable.

The reviewed steak is found by accessing the [:steak_id] in the params hash. The steak's rating will be updated with the value returned by the instance method calc_avg_rating:

class Steak < ApplicationRecord
    def calc_avg_rating
        self.reviews.average(:rating)
    end
end

The method harnesses Active Record associations and methods to calculate the average rating from the steak's associated reviews.

The Best Steak page fetches from the API endpoint /steaks/highest-rated and renders the corresponding steak with its associated reviews. On the backend, the endpoint points to the highest_rated method in the Steaks Controller:

def highest_rated
    max = Steak.maximum(:rating)
    render json: Steak.where(rating: max)
end

On the page, the steak's associated reviews are rendered as well thanks to the has_many :reviews relationship established in the Steak Serializer:

class SteakSerializer < ActiveModel::Serializer
    attributes :id, :restaurant, :rating
    has_many :reviews
end

Similarly, the My Reviews page displays Reviews associated with the current user instance utilizing the same association but in the User Serializer:

class UserSerializer < ActiveModel::Serializer
  attributes :id, :username, :fav_steak

  has_many :reviews
  has_many :steaks
end

Finally, on the Add Steak page the user can create a new instance of the Steak class and leave a corresponding review:
Add Steak Page
And there you have it, the Steak Whizard. Give it a spin and let me know your thoughts - who knows, you may even find your favorite Philly Cheesesteak along the way.


This content originally appeared on DEV Community and was authored by Michael Lobman


Print Share Comment Cite Upload Translate Updates
APA

Michael Lobman | Sciencx (2022-04-01T14:52:39+00:00) Steak Whizard. Retrieved from https://www.scien.cx/2022/04/01/steak-whizard/

MLA
" » Steak Whizard." Michael Lobman | Sciencx - Friday April 1, 2022, https://www.scien.cx/2022/04/01/steak-whizard/
HARVARD
Michael Lobman | Sciencx Friday April 1, 2022 » Steak Whizard., viewed ,<https://www.scien.cx/2022/04/01/steak-whizard/>
VANCOUVER
Michael Lobman | Sciencx - » Steak Whizard. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/04/01/steak-whizard/
CHICAGO
" » Steak Whizard." Michael Lobman | Sciencx - Accessed . https://www.scien.cx/2022/04/01/steak-whizard/
IEEE
" » Steak Whizard." Michael Lobman | Sciencx [Online]. Available: https://www.scien.cx/2022/04/01/steak-whizard/. [Accessed: ]
rf:citation
» Steak Whizard | Michael Lobman | Sciencx | https://www.scien.cx/2022/04/01/steak-whizard/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.