Merge branch 'atomaka/feature/post' into 'master'
Add posts Not complete, but implemented basic posting to subcreddits. Right now, links aren't taken into account (but basic modeling is in). Enough to continue. See merge request !11
This commit is contained in:
commit
1e3665ab42
22 changed files with 445 additions and 2 deletions
3
app/assets/javascripts/posts.coffee
Normal file
3
app/assets/javascripts/posts.coffee
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# Place all the behaviors and hooks related to the matching controller here.
|
||||||
|
# All this logic will automatically be available in application.js.
|
||||||
|
# You can use CoffeeScript in this file: http://coffeescript.org/
|
3
app/assets/stylesheets/posts.scss
Normal file
3
app/assets/stylesheets/posts.scss
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
// Place all the styles related to the Posts controller here.
|
||||||
|
// They will automatically be included in application.css.
|
||||||
|
// You can use Sass (SCSS) here: http://sass-lang.com/
|
55
app/controllers/posts_controller.rb
Normal file
55
app/controllers/posts_controller.rb
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
class PostsController < ApplicationController
|
||||||
|
before_filter :set_post, except: [:index, :new, :create]
|
||||||
|
before_filter :set_subcreddit
|
||||||
|
|
||||||
|
def show
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@post = Post.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@post = @subcreddit.posts.build(post_params)
|
||||||
|
@post.user = current_user
|
||||||
|
|
||||||
|
if @post.save
|
||||||
|
redirect_to subcreddit_post_path(@subcreddit, @post),
|
||||||
|
notice: 'Post created'
|
||||||
|
else
|
||||||
|
render :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @post.update(post_params)
|
||||||
|
redirect_to subcreddit_post_path(@subcreddit, @post),
|
||||||
|
notice: 'Post was updated'
|
||||||
|
else
|
||||||
|
render :edit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@post.destroy
|
||||||
|
|
||||||
|
redirect_to subcreddits_path(@subcreddit), notice: 'Post was deleted'
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def post_params
|
||||||
|
params.require(:post).permit(:title, :link, :content, :subcreddit_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_subcreddit
|
||||||
|
@subcreddit = Subcreddit.find_by_slug(params['subcreddit_id'])
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_post
|
||||||
|
@post = Post.find(params[:id])
|
||||||
|
end
|
||||||
|
end
|
15
app/models/post.rb
Normal file
15
app/models/post.rb
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
class Post < ActiveRecord::Base
|
||||||
|
belongs_to :user
|
||||||
|
belongs_to :subcreddit
|
||||||
|
|
||||||
|
validates :title,
|
||||||
|
presence: true,
|
||||||
|
length: { maximum: 300 }
|
||||||
|
|
||||||
|
validates :content,
|
||||||
|
length: { maximum: 15000 }
|
||||||
|
|
||||||
|
def to_param
|
||||||
|
"#{self.id}-#{self.title.parameterize}"
|
||||||
|
end
|
||||||
|
end
|
|
@ -2,6 +2,7 @@ RESERVED_SLUGS = %w(new edit)
|
||||||
|
|
||||||
class Subcreddit < ActiveRecord::Base
|
class Subcreddit < ActiveRecord::Base
|
||||||
belongs_to :owner, class_name: 'User'
|
belongs_to :owner, class_name: 'User'
|
||||||
|
has_many :posts
|
||||||
|
|
||||||
attr_accessor :closed
|
attr_accessor :closed
|
||||||
|
|
||||||
|
|
7
app/views/posts/_form.html.slim
Normal file
7
app/views/posts/_form.html.slim
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
= simple_form_for [subcreddit, post] do |f|
|
||||||
|
.form-inputs
|
||||||
|
= f.input :title
|
||||||
|
= f.input :link
|
||||||
|
= f.input :content
|
||||||
|
.form-actions
|
||||||
|
= f.button :submit
|
0
app/views/posts/create.html.slim
Normal file
0
app/views/posts/create.html.slim
Normal file
0
app/views/posts/destroy.html.slim
Normal file
0
app/views/posts/destroy.html.slim
Normal file
1
app/views/posts/edit.html.slim
Normal file
1
app/views/posts/edit.html.slim
Normal file
|
@ -0,0 +1 @@
|
||||||
|
= render 'form', subcreddit: @subcreddit, post: @post
|
1
app/views/posts/new.html.slim
Normal file
1
app/views/posts/new.html.slim
Normal file
|
@ -0,0 +1 @@
|
||||||
|
= render 'form', subcreddit: @subcreddit, post: @post
|
2
app/views/posts/show.html.slim
Normal file
2
app/views/posts/show.html.slim
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
h1= @post.title
|
||||||
|
= @post.content
|
0
app/views/posts/update.html.slim
Normal file
0
app/views/posts/update.html.slim
Normal file
|
@ -1,3 +1,8 @@
|
||||||
h1= @subcreddit.name
|
h1= @subcreddit.name
|
||||||
- if @subcreddit.closed?
|
- if @subcreddit.closed?
|
||||||
= "Board has been closed"
|
= "Board has been closed"
|
||||||
|
- else
|
||||||
|
= link_to 'New Post', new_subcreddit_post_path(@subcreddit)
|
||||||
|
ul
|
||||||
|
- @subcreddit.posts.each do |post|
|
||||||
|
li= link_to post.title, [@subcreddit, post]
|
||||||
|
|
|
@ -3,7 +3,10 @@ Rails.application.routes.draw do
|
||||||
get 'signin', to: 'user_sessions#new', as: :signin
|
get 'signin', to: 'user_sessions#new', as: :signin
|
||||||
get 'signout', to: 'user_sessions#destroy', as: :signout
|
get 'signout', to: 'user_sessions#destroy', as: :signout
|
||||||
|
|
||||||
resources :subcreddits, path: 'c', except: [:destroy]
|
resources :subcreddits, path: 'c', except: [:destroy] do
|
||||||
|
resources :posts, except: [:index]
|
||||||
|
end
|
||||||
|
|
||||||
resources :user_sessions, only: [:new, :create, :destroy]
|
resources :user_sessions, only: [:new, :create, :destroy]
|
||||||
resources :users, only: [:new, :create]
|
resources :users, only: [:new, :create]
|
||||||
|
|
||||||
|
|
13
db/migrate/20150714200610_create_posts.rb
Normal file
13
db/migrate/20150714200610_create_posts.rb
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
class CreatePosts < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
create_table :posts do |t|
|
||||||
|
t.references :user, index: true, foreign_key: true
|
||||||
|
t.references :subcreddit, index: true, foreign_key: true
|
||||||
|
t.string :title
|
||||||
|
t.string :link
|
||||||
|
t.text :content
|
||||||
|
|
||||||
|
t.timestamps null: false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
15
db/schema.rb
15
db/schema.rb
|
@ -11,7 +11,20 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 20150713045745) do
|
ActiveRecord::Schema.define(version: 20150714200610) do
|
||||||
|
|
||||||
|
create_table "posts", force: :cascade do |t|
|
||||||
|
t.integer "user_id"
|
||||||
|
t.integer "subcreddit_id"
|
||||||
|
t.string "title"
|
||||||
|
t.string "link"
|
||||||
|
t.text "content"
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.datetime "updated_at", null: false
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index "posts", ["subcreddit_id"], name: "index_posts_on_subcreddit_id"
|
||||||
|
add_index "posts", ["user_id"], name: "index_posts_on_user_id"
|
||||||
|
|
||||||
create_table "subcreddits", force: :cascade do |t|
|
create_table "subcreddits", force: :cascade do |t|
|
||||||
t.integer "owner_id"
|
t.integer "owner_id"
|
||||||
|
|
162
spec/controllers/posts_controller_spec.rb
Normal file
162
spec/controllers/posts_controller_spec.rb
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe PostsController, type: :controller do
|
||||||
|
let!(:user) { build(:user) }
|
||||||
|
let!(:subcreddit) { create(:subcreddit) }
|
||||||
|
let(:data) do
|
||||||
|
{
|
||||||
|
title: 'A New Post',
|
||||||
|
content: 'Here is some content for that post'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
before(:each) do
|
||||||
|
allow_any_instance_of(ApplicationController)
|
||||||
|
.to receive(:current_user).and_return(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#show' do
|
||||||
|
let(:post) { create(:post) }
|
||||||
|
before(:each) { get :show, subcreddit_id: post.subcreddit, id: post }
|
||||||
|
|
||||||
|
|
||||||
|
it 'should render :show' do
|
||||||
|
expect(response).to render_template(:show)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should assign correct Post to @post' do
|
||||||
|
expect(assigns(:post)).to eq(post)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#new' do
|
||||||
|
let(:post) { build(:post) }
|
||||||
|
before(:each) { get :new, subcreddit_id: post.subcreddit }
|
||||||
|
|
||||||
|
it 'should render :new' do
|
||||||
|
expect(response).to render_template(:new)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should assign new Post to @post' do
|
||||||
|
expect(assigns(:post)).to be_a_new(Post)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#create' do
|
||||||
|
|
||||||
|
context 'with valid data' do
|
||||||
|
it 'should create a post' do
|
||||||
|
expect { post :create, subcreddit_id: subcreddit, post: data }
|
||||||
|
.to change(Post, :count).by(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should redirect to the new post' do
|
||||||
|
expect(post :create, subcreddit_id: subcreddit, post: data)
|
||||||
|
.to redirect_to(subcreddit_post_path(assigns(:post).subcreddit,
|
||||||
|
assigns(:post)))
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should send a notice flash message' do
|
||||||
|
post :create, subcreddit_id: subcreddit, post: data
|
||||||
|
|
||||||
|
expect(flash[:notice]).to be_present
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with invalid data' do
|
||||||
|
before(:each) { data['title'] = '' }
|
||||||
|
|
||||||
|
it 'should not create a post' do
|
||||||
|
expect { post :create, subcreddit_id: subcreddit, post: data }
|
||||||
|
.to change(Post, :count).by(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should render :new' do
|
||||||
|
post :create, subcreddit_id: subcreddit, post: data
|
||||||
|
|
||||||
|
expect(response).to render_template(:new)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context '#edit' do
|
||||||
|
let!(:post) { create(:post) }
|
||||||
|
before(:each) { get :edit, id: post, subcreddit_id: post.subcreddit }
|
||||||
|
|
||||||
|
context 'with valid post' do
|
||||||
|
it 'should render :edit' do
|
||||||
|
expect(response).to render_template(:edit)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should assign correct Post to @post' do
|
||||||
|
expect(assigns(:post)).to eq(post)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context '#update' do
|
||||||
|
let!(:post) { create(:post) }
|
||||||
|
let(:data) do
|
||||||
|
{
|
||||||
|
title: 'New title',
|
||||||
|
content: 'New content'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with valid data' do
|
||||||
|
before(:each) do
|
||||||
|
put :update, id: post, subcreddit_id: post.subcreddit, post: data
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should assign correct Post to @post' do
|
||||||
|
expect(assigns(:post)).to eq(post)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should update the post' do
|
||||||
|
post.reload
|
||||||
|
|
||||||
|
expect(post.title).to eq(data[:title])
|
||||||
|
expect(post.content).to eq(data[:content])
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should redirect to the post' do
|
||||||
|
expect(response)
|
||||||
|
.to redirect_to(subcreddit_post_path(assigns(:post).subcreddit,
|
||||||
|
assigns(:post)))
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should display a notice flash message' do
|
||||||
|
expect(flash[:notice]).to be_present
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with invalid data' do
|
||||||
|
before(:each) { data[:title] = '' }
|
||||||
|
|
||||||
|
it 'should render :edit' do
|
||||||
|
put :update, id: post, subcreddit_id: post.subcreddit, post: data
|
||||||
|
|
||||||
|
expect(response).to render_template(:edit)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context '#destroy' do
|
||||||
|
let!(:post) { create(:post, subcreddit: subcreddit) }
|
||||||
|
|
||||||
|
it 'should delete the post' do
|
||||||
|
expect { delete :destroy, subcreddit_id: subcreddit, id: post }
|
||||||
|
.to change(Post, :count).by(-1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should redirect to the subcreddit index' do
|
||||||
|
expect(delete :destroy, subcreddit_id: subcreddit, id: post)
|
||||||
|
.to redirect_to(subcreddits_path(subcreddit))
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should flash notify that the post was deleted' do
|
||||||
|
delete :destroy, subcreddit_id: subcreddit, id: post
|
||||||
|
|
||||||
|
expect(flash[:notice]).to be_present
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
9
spec/factories/post_factory.rb
Normal file
9
spec/factories/post_factory.rb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
FactoryGirl.define do
|
||||||
|
factory :post do
|
||||||
|
user
|
||||||
|
subcreddit
|
||||||
|
title { Faker::Lorem.sentence }
|
||||||
|
link ''
|
||||||
|
content { Faker::Lorem.paragraph }
|
||||||
|
end
|
||||||
|
end
|
32
spec/features/posts/edit_post_spec.rb
Normal file
32
spec/features/posts/edit_post_spec.rb
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe 'Edit Post', type: :feature do
|
||||||
|
context 'when signed in' do
|
||||||
|
let!(:user) { create(:user) }
|
||||||
|
let!(:subcreddit) { create(:subcreddit) }
|
||||||
|
let!(:post) { create(:post, subcreddit: subcreddit, user: user) }
|
||||||
|
let(:new_post) { build_stubbed(:post) }
|
||||||
|
|
||||||
|
before(:each) { signin(user: user) }
|
||||||
|
|
||||||
|
context 'with valid data' do
|
||||||
|
before(:each) do
|
||||||
|
visit edit_subcreddit_post_path(subcreddit, post)
|
||||||
|
|
||||||
|
fill_in :post_title, with: new_post.title
|
||||||
|
fill_in :post_link, with: new_post.link
|
||||||
|
fill_in :post_content, with: new_post.content
|
||||||
|
|
||||||
|
click_button 'Update Post'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should notify that the post was edited' do
|
||||||
|
expect(page).to have_content('updated')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should show the post' do
|
||||||
|
expect(page).to have_content(new_post.title)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
15
spec/features/posts/lists_posts_spec.rb
Normal file
15
spec/features/posts/lists_posts_spec.rb
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe 'List Posts', type: :feature do
|
||||||
|
let!(:subcreddit) { create(:subcreddit) }
|
||||||
|
let!(:posts) { 10.times.collect { create(:post, subcreddit: subcreddit) } }
|
||||||
|
|
||||||
|
it 'should list all posts for a subcreddit' do
|
||||||
|
visit subcreddit_path(subcreddit)
|
||||||
|
|
||||||
|
posts.each do |post|
|
||||||
|
expect(page)
|
||||||
|
.to have_link(post.title, subcreddit_post_path(post, post.subcreddit))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
49
spec/features/posts/new_post_spec.rb
Normal file
49
spec/features/posts/new_post_spec.rb
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe 'New Post', type: :feature do
|
||||||
|
context 'when signed in' do
|
||||||
|
let!(:user) { create(:user) }
|
||||||
|
let!(:subcreddit) { create(:subcreddit) }
|
||||||
|
let!(:post) { build(:post, subcreddit: subcreddit) }
|
||||||
|
|
||||||
|
before(:each) { signin(user: user) }
|
||||||
|
|
||||||
|
context 'with valid data' do
|
||||||
|
before(:each) do
|
||||||
|
visit new_subcreddit_post_path(subcreddit)
|
||||||
|
|
||||||
|
fill_in :post_title, with: post.title
|
||||||
|
fill_in :post_link, with: post.link
|
||||||
|
fill_in :post_content, with: post.content
|
||||||
|
|
||||||
|
click_button 'Create Post'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should notify that a new post was created' do
|
||||||
|
expect(page).to have_content('created')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should display the new post' do
|
||||||
|
expect(page).to have_content(post.title)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with invalid data' do
|
||||||
|
before(:each) do
|
||||||
|
visit new_subcreddit_post_path(subcreddit)
|
||||||
|
|
||||||
|
post.title = ''
|
||||||
|
|
||||||
|
fill_in :post_title, with: post.title
|
||||||
|
fill_in :post_link, with: post.link
|
||||||
|
fill_in :post_content, with: post.content
|
||||||
|
|
||||||
|
click_button 'Create Post'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should display errors' do
|
||||||
|
expect(page).to have_content("can't be blank")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
54
spec/models/post_spec.rb
Normal file
54
spec/models/post_spec.rb
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe Post, type: :model do
|
||||||
|
let(:post) { build(:post) }
|
||||||
|
|
||||||
|
it { should belong_to(:user) }
|
||||||
|
it { should belong_to(:subcreddit) }
|
||||||
|
|
||||||
|
context 'with valid data' do
|
||||||
|
it 'should be valid' do
|
||||||
|
expect(post).to be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should allow blank content' do
|
||||||
|
post.content = ''
|
||||||
|
|
||||||
|
expect(post).to be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should allow a blank link' do
|
||||||
|
post.link = ''
|
||||||
|
|
||||||
|
expect(post).to be_valid
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with invalid data' do
|
||||||
|
it 'should not allow a blank title' do
|
||||||
|
post.title = ''
|
||||||
|
|
||||||
|
expect(post).to be_invalid
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should not allow a long title' do
|
||||||
|
post.title = 'a' * 301
|
||||||
|
|
||||||
|
expect(post).to be_invalid
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should not allow long content' do
|
||||||
|
post.content = 'a' * 15001
|
||||||
|
|
||||||
|
expect(post).to be_invalid
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context '#to_param' do
|
||||||
|
it 'generates the correct param' do
|
||||||
|
post.save
|
||||||
|
|
||||||
|
expect(post.to_param).to eq("#{post.id}-#{post.title.parameterize}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue