Last active
November 24, 2020 11:26
-
-
Save MaiAbuthraa/58f6fe89f76cfd297d83ed130f4c8391 to your computer and use it in GitHub Desktop.
Rails Best Practices
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## The first exercise: Fat Model Skinny Controller | |
# Fat Model, Skinny Controller: refers to how the M and C parts of MVC ideally work together. | |
# Namely, any non-response-related logic should go in the model, ideally in a nice, testable method. | |
# Meanwhile, the “skinny” controller is simply a nice interface between the view and model. | |
# Chaeck this artical: https://dev.to/kputra/rails-skinny-controller-skinny-model-5f2k | |
#### Bad Code #### | |
# app/controllers/posts_controller.rb | |
class PostsController < ApplicationController | |
# share this in your wall | |
def reshare | |
post = Post.find(params[:id]) | |
if post.user == current_user | |
flash[:notice] = "Sorry, you can't reshare your own post" | |
elsif post.reshare.where(user_id: current_user.id).present? | |
flash[:notice] = "You already shared this post" | |
else | |
new_post = Post.new | |
new_post.status = "Share #{post.user.name} #{post.status}" | |
new_post.origianl_post = post | |
new_post.user = current_user | |
new_post.save | |
flash[:notice] = "Succesfully shared" | |
end | |
redirect_to post | |
end | |
end | |
#### Good Code / V1 #### | |
# app/controllers/posts_controller.rb | |
class PostsController < ApplicationController | |
def reshare | |
post = Post.find(params[:id]) | |
flash[:notice] = post.posted_by(current_user) | |
redirect_to post | |
end | |
end | |
# app/models/post.rb | |
class Post < ActiveRecord::base | |
def posted_by(user) | |
if self.user == user | |
"Sorry, you can't reshare your own post" | |
elsif self.reshare.where(user_id: user.id).present? | |
"You already shared this post" | |
else | |
# this is not good code | |
new_post = Post.new | |
new_post.status = "Share: #{self.user.name} #{self.status}" | |
new_post.origianl_post = self | |
new_post.user = user | |
new_post.save | |
"Succesfully shared" | |
end | |
end | |
end | |
#### Good Code / V2 #### | |
# app/controllers/posts_controller.rb | |
class PostsController < ApplicationController | |
before_action :set_post, only: [:reshare] | |
def reshare | |
flash[:notice] = @post.posted_by(current_user) | |
redirect_to @post | |
end | |
private | |
def set_post | |
@post = Post.find(params[:id]) | |
end | |
end | |
# app/models/post.rb | |
class Post < ActiveRecord::base | |
def posted_by(user) | |
if self.user == user | |
"Sorry, you can't reshare your own post" | |
elsif self.reshare.where(user_id: user.id).present? | |
"You already shared this post" | |
else | |
user.posts.create( | |
status:"Share: #{self.user.name} #{self.status}", | |
origianl_post: self | |
) | |
"Succesfully shared" | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Scope It Out | |
#### Bad Code #### | |
# app/controllers/posts_controller.rb | |
class PostsController < ApplicationController | |
# In the Index function | |
# I want to have my posts & most 5 trending posts | |
def index | |
@posts = Post.where(user_id: current_user.id). | |
order("created_at desc"). | |
limit(10) | |
@trending = Post.where('start_trending > ', 1.day.ago). | |
order("mentions desc"). | |
limit(5) | |
end | |
end | |
#### Good Code #### | |
# app/controllers/posts_controller.rb | |
class PostsController < ApplicationController | |
@posts = current_user.posts.limit(10) | |
# we can ignore our default_scope | |
# @posts = current_user.posts.unscoped.order(:status).limit(10) | |
@trending = Post.trending(5) | |
end | |
# app/models/post.rb | |
class Post < ActiveRecord::base | |
default_scope order("created_at desc") | |
scope :trending, lambda do |num = nil| | |
where('start_trending > ', 1.day.ago). | |
order("mentions desc"). | |
limit(num) | |
end | |
# why we use lambda function: if we call this scope again, we will get 1.day.ago (ex: Mon, 23 Nov 2020 07:54:55 UTC +00:00) | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment