Instagram Challenge View on Heroku
- Approach
- How To Run
- Design Principles Used
- Challenges
- What I Have Learnt
- Tests
- Technologies Used
- Future Features
Instagram Challenge was a task to create a RESTful Ruby-on-Rails CRUD application. I started by allowing anyone to upload a picture and give it a description. Then I implemented the ability to be able to edit the description or delete the entire post. It was obvious after that that users would be needed in order to stop anyone being able to delete peoples posts.
I used the Devise gem for user authentication, adding the ability to login with usernames instead of email addresses and you would with the real Instagram.
Given some more time I would like to implement more features.
$ git clone https://github.com/leggsimon/instagram-challenge
$ cd instagram-challenge
$ gem install bundle
$ bundle install
$ bin/rake db:create RAILS_ENV=development
$ bin/rake db:create RAILS_ENV=test
$ bin/rake db:migrate RAILS_ENV=development
$ bin/rake db:migrate RAILS_ENV=test
$ rails s
Go to http://localhost:3000
$ rspec
I used a combination of Behavior Driven Design (BDD) and Test Driven Design (TDD) in this project, writing feature tests that covered a user's specific behavior when signing up and in and uploading, editing and deleting pictures. Using Capybara's syntax to be able to click_link
s and fill_in
forms as a user would when navigating the site.
The main challenge I had found with this was making the site scaleable with different sized screens, but I finally figured out how to use Bootstrap's columns using the syntax,.col-SIZE-8 .col-SIZE-offset-2
, within the tag's class. Where SIZE
can be
xs
for extra small devices eg. phonessm
for small devices eg. tabletsmd
&lg
for medium and large desktops
In order to check the current_user
was able to update or destroy the post while at the same time keeping my controller skinny and doing minimal business logic in it, I created these methods in my pictures.rb
model.
# app/models/pictures.rb
def created_by?(user)
self.user == user
end
def destroy_as(user)
unless created_by? user
errors.add(:user, 'cannot delete this picture')
return false
end
destroy
end
def update_as(user, params)
unless created_by? user
errors.add(:user, 'cannot edit this picture')
return false
end
update(params)
end
This allowed me to put the responsibility on the model to say whether the pictures were able to be updated or destroyed by the current_user
.
# app/controllers/pictures_controller.rb
def update
picture = Picture.find(params[:id])
if picture.update_as(current_user, picture_params)
redirect_to picture_path
else
flash[:alert] = picture.errors
redirect_to picture_path
end
end
def destroy
picture = Picture.find(params[:id])
if picture.destroy_as current_user
flash[:notice] = 'Picture deleted successfully'
redirect_to pictures_path
else
flash[:alert] = picture.errors
redirect_to picture_path
end
end
Commenting
allows users to leave comments
cannot leave a blank comment
Pictures
no pictures have been added
should display a prompt to upload a picture
adding pictures
is not valid with no description
pictures have been added
displays pictures
viewing pictures
lets a user view a picture
when signed in a user can
edit their picture's description
delete their picture
users cannot
edit other users' pictures
delete other users' pictures
User can sign in and out
user not signed in and on the homepage
should see a 'sign in' link and a 'sign up' link
should not see 'sign out' link
user signed in on the homepage
should see 'sign out' link
should not see a 'sign in' link and a 'sign up' link
Comment
is invalid if the comment is blank
Picture
should have many comments dependent => destroy
should belong to user
User
should have many pictures
Given more time I would like to implement the following features to this clone of Instagram.