Merge branch 'atomaka/feature/simple-user-profile' into 'master'
Add a simple user profile Adds a profile and links to it. Also includes a refactor on the page header. See merge request !16
This commit is contained in:
commit
76610ede87
21 changed files with 128 additions and 18 deletions
|
@ -1,4 +1,9 @@
|
|||
class UsersController < ApplicationController
|
||||
def show
|
||||
@user = User.friendly.find(params[:id])
|
||||
@comments = @user.comments
|
||||
end
|
||||
|
||||
def new
|
||||
@user = User.new
|
||||
end
|
||||
|
|
|
@ -3,6 +3,10 @@ module ApplicationHelper
|
|||
bootstrap_classes[flash_type] || flash_type.to_s
|
||||
end
|
||||
|
||||
def page_header
|
||||
content_for(:title) || ''
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def bootstrap_classes
|
||||
|
|
|
@ -16,13 +16,12 @@ class Subcreddit < ActiveRecord::Base
|
|||
presence: true,
|
||||
format: /\A(?! )[a-z0-9 ]*(?<! )\z/i,
|
||||
uniqueness: true, #{ case_sensitive: false },
|
||||
length: { minimum: 3, maximum: 21 }
|
||||
length: { minimum: 3, maximum: 21 },
|
||||
sluguuidless: true
|
||||
|
||||
validates :closed,
|
||||
format: /\A[01]?\z/
|
||||
|
||||
validate :slug_does_not_have_uuid
|
||||
|
||||
def closed?
|
||||
self.closed_at != nil
|
||||
end
|
||||
|
@ -36,10 +35,4 @@ class Subcreddit < ActiveRecord::Base
|
|||
self.closed_at = nil
|
||||
end
|
||||
end
|
||||
|
||||
def slug_does_not_have_uuid
|
||||
if self.slug.match /([a-z0-9]+\-){4}[a-z0-9]+\z/
|
||||
errors.add(:name, 'must be unique')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
class User < ActiveRecord::Base
|
||||
extend FriendlyId
|
||||
|
||||
has_secure_password
|
||||
|
||||
has_many :comments
|
||||
has_many :posts
|
||||
|
||||
friendly_id :username, use: :slugged
|
||||
|
||||
before_save :downcase_email
|
||||
|
||||
validates :email, presence: true, uniqueness: true
|
||||
validates :username, presence: true, uniqueness: true
|
||||
validates :username, presence: true, uniqueness: true, sluguuidless: true
|
||||
validates :password, length: { minimum: 8 }
|
||||
|
||||
private
|
||||
|
|
7
app/validators/sluguuidless_validator.rb
Normal file
7
app/validators/sluguuidless_validator.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
class SluguuidlessValidator < ActiveModel::EachValidator
|
||||
def validate_each(record, attribute, value)
|
||||
if record.slug.match /([a-z0-9]+\-){4}[a-z0-9]+\z/
|
||||
record.errors[attribute] << 'must be unique'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -10,8 +10,7 @@
|
|||
= link_to 'Creddit', root_path, class: 'navbar-brand'
|
||||
.collapse.navbar-collapse
|
||||
ul.nav.navbar-nav
|
||||
- if @subcreddit && @subcreddit.name
|
||||
li= link_to @subcreddit.name, @subcreddit
|
||||
li= page_header
|
||||
ul.nav.navbar-nav.navbar-right
|
||||
- if logged_in?
|
||||
li= link_to 'Sign Out', signout_path
|
||||
|
|
|
@ -18,4 +18,4 @@
|
|||
.title Moderators
|
||||
.box
|
||||
ul
|
||||
li= @subcreddit.owner_username
|
||||
li= link_to @subcreddit.owner_username, @subcreddit.owner
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
.comment
|
||||
p.details= "#{comment.user_username} X points #{distance_of_time_in_words comment.created_at, Time.now} ago"
|
||||
p.details
|
||||
== link_to comment.user_username, comment.user
|
||||
= " X points #{distance_of_time_in_words comment.created_at, Time.now} ago"
|
||||
p.content= comment.content
|
||||
ul.links.list-inline
|
||||
li= link_to 'permalink', subcreddit_post_comment_path(subcreddit, post, comment)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
- content_for(:title, link_to(@subcreddit.name, @subcreddit))
|
||||
== render 'posts/post', post: @post
|
||||
.alert.alert-info.in-page
|
||||
p you are viewing a single comment's thread.
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
.posts.contents
|
||||
.post.show
|
||||
p.title= link_to post.title, [post.subcreddit, post]
|
||||
p.details= "submitted #{distance_of_time_in_words post.created_at, Time.now} ago by #{post.user_username}"
|
||||
p.details
|
||||
= "submitted #{distance_of_time_in_words post.created_at, Time.now} ago by "
|
||||
== link_to post.user_username, post.user
|
||||
p.content= post.content
|
||||
ul.links.list-inline
|
||||
li= link_to "#{post.comments_count} comments", subcreddit_post_path(post.subcreddit, post)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
- content_for(:title, link_to(@subcreddit.name, @subcreddit))
|
||||
== render 'post', post: @post
|
||||
- if @post.comments?
|
||||
.title= "all #{@post.comments_count} comments"
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
- content_for(:title) { link_to @subcreddit.name, @subcreddit }
|
||||
- if @subcreddit.closed?
|
||||
= "Board has been closed"
|
||||
- else
|
||||
|
@ -7,7 +8,9 @@
|
|||
li
|
||||
.post
|
||||
p.title= link_to post.title, subcreddit_post_path(@subcreddit, post)
|
||||
p.details= "submitted #{distance_of_time_in_words post.created_at, Time.now} ago by #{post.user_username}"
|
||||
p.details
|
||||
= "submitted #{distance_of_time_in_words post.created_at, Time.now} ago by "
|
||||
== link_to post.user_username, post.user
|
||||
ul.links.list-inline
|
||||
li= link_to "#{post.comments_count} comments", subcreddit_post_path(@subcreddit, post)
|
||||
li= link_to 'share', ''
|
||||
|
|
5
app/views/users/show.html.slim
Normal file
5
app/views/users/show.html.slim
Normal file
|
@ -0,0 +1,5 @@
|
|||
- content_for(:title, link_to(@user.username, @user))
|
||||
|
||||
.comments.contents
|
||||
- @comments.each do |comment|
|
||||
== render 'comments/comment', subcreddit: comment.post.subcreddit, post: comment.post, comment: comment
|
|
@ -22,5 +22,8 @@ module Creddit
|
|||
|
||||
# Do not swallow errors in after_commit/after_rollback callbacks.
|
||||
config.active_record.raise_in_transactional_callbacks = true
|
||||
|
||||
# So our console continues to work
|
||||
config.autoload_paths += %W["#{config.root}/app/validators/"]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,7 +10,7 @@ Rails.application.routes.draw do
|
|||
end
|
||||
|
||||
resources :user_sessions, only: [:new, :create, :destroy]
|
||||
resources :users, only: [:new, :create]
|
||||
resources :users, path: 'u', only: [:show, :new, :create]
|
||||
|
||||
root to: 'subcreddits#index'
|
||||
end
|
||||
|
|
6
db/migrate/20150806191452_add_friendly_id_to_user.rb
Normal file
6
db/migrate/20150806191452_add_friendly_id_to_user.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
class AddFriendlyIdToUser < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :users, :slug, :string
|
||||
add_index :users, :slug, unique: true
|
||||
end
|
||||
end
|
|
@ -11,7 +11,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20150804145405) do
|
||||
ActiveRecord::Schema.define(version: 20150806191452) do
|
||||
|
||||
create_table "comments", force: :cascade do |t|
|
||||
t.integer "user_id"
|
||||
|
@ -84,6 +84,9 @@ ActiveRecord::Schema.define(version: 20150804145405) do
|
|||
t.string "password_digest"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "slug"
|
||||
end
|
||||
|
||||
add_index "users", ["slug"], name: "index_users_on_slug", unique: true
|
||||
|
||||
end
|
||||
|
|
|
@ -1,6 +1,25 @@
|
|||
require 'rails_helper'
|
||||
|
||||
describe UsersController, type: :controller do
|
||||
describe '#show' do
|
||||
let(:user) { create(:user) }
|
||||
before(:each) { get :show, id: user }
|
||||
|
||||
it 'should render :show' do
|
||||
expect(response).to render_template(:show)
|
||||
end
|
||||
|
||||
it 'should assign user comments to @comments' do
|
||||
comments = 5.times.collect { create(:comment, user: user) }
|
||||
|
||||
expect(assigns(:comments)).to eq(comments)
|
||||
end
|
||||
|
||||
it 'should assign requested User to @user' do
|
||||
expect(assigns(:user)).to eq(user)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#new' do
|
||||
it 'should render :new' do
|
||||
get :new
|
||||
|
|
23
spec/features/users/profile_spec.rb
Normal file
23
spec/features/users/profile_spec.rb
Normal file
|
@ -0,0 +1,23 @@
|
|||
require 'rails_helper'
|
||||
|
||||
describe 'Profile', type: :feature do
|
||||
let!(:user) { create(:user) }
|
||||
|
||||
it 'should display a user profile' do
|
||||
visit user_path(user)
|
||||
|
||||
expect(page).to have_content(user.username)
|
||||
end
|
||||
|
||||
context 'when the user has commented' do
|
||||
let!(:comments) { 5.times.collect { create(:comment, user: user) } }
|
||||
|
||||
it 'should display user comments' do
|
||||
visit user_path(user)
|
||||
|
||||
comments.each do |comment|
|
||||
expect(page).to have_content(comment.content)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -26,4 +26,20 @@ describe ApplicationHelper do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#page_header' do
|
||||
context 'when title is provided' do
|
||||
it 'should return the set title' do
|
||||
allow(helper).to receive(:content_for).with(:title).and_return('Test')
|
||||
|
||||
expect(helper.page_header).to eq 'Test'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when title is not provided' do
|
||||
it 'should return blank' do
|
||||
expect(helper.page_header).to be_blank
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
require 'rails_helper'
|
||||
|
||||
require 'securerandom'
|
||||
|
||||
describe User, type: :model do
|
||||
let(:user) { build(:user) }
|
||||
|
||||
it { should have_secure_password }
|
||||
|
||||
it { should have_many :comments }
|
||||
it { should have_many :posts }
|
||||
|
||||
context 'with valid data' do
|
||||
it 'should be valid' do
|
||||
expect(user).to be_valid
|
||||
|
@ -44,5 +49,11 @@ describe User, type: :model do
|
|||
user.password = 'a' * 4
|
||||
expect(user).to be_invalid
|
||||
end
|
||||
|
||||
it 'should not allow a slug with a UUID' do
|
||||
user.slug = "test-#{SecureRandom.uuid}"
|
||||
|
||||
expect(user).to be_invalid
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue