Skip to content

Commit

Permalink
Merge pull request #4 from ufacode/newsletter
Browse files Browse the repository at this point in the history
Update Newsletter page
  • Loading branch information
mpakus authored Sep 20, 2016
2 parents 2d07891 + 0c4529d commit 25736b6
Show file tree
Hide file tree
Showing 27 changed files with 279 additions and 7 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,5 @@ bower.json

# Ignore vim files
*.swp
*.swo
*.swo
.vimrc
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ gem 'byebug', group: [:development, :test], platform: :mri
gem 'bullet', group: [:development]
gem 'coffee-rails', '~> 4.2'
gem 'database_cleaner', group: [:development, :test]
gem 'awesome_print', group: [:development, :test]
gem 'shoulda-matchers', '~> 3.1', group: [:test]
gem 'devise'
gem 'factory_girl_rails', group: [:development, :test]
gem 'faker', group: [:development, :test]
Expand Down
5 changes: 5 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ GEM
ast (2.3.0)
autoprefixer-rails (6.4.0.1)
execjs
awesome_print (1.7.0)
bcrypt (3.1.11)
better_errors (2.1.1)
coderay (>= 1.0.0)
Expand Down Expand Up @@ -211,6 +212,8 @@ GEM
tilt (>= 1.1, < 3)
sextant (0.2.4)
rails (>= 3.2)
shoulda-matchers (3.1.1)
activesupport (>= 4.0.0)
slim (3.0.7)
temple (~> 0.7.6)
tilt (>= 1.3.3, < 2.1)
Expand Down Expand Up @@ -254,6 +257,7 @@ PLATFORMS
DEPENDENCIES
aasm
annotate
awesome_print
better_errors
binding_of_caller
bootstrap-generators
Expand All @@ -279,6 +283,7 @@ DEPENDENCIES
russian
sass-rails (~> 5.0)
sextant
shoulda-matchers (~> 3.1)
slim-rails
spring
spring-watcher-listen (~> 2.0.0)
Expand Down
5 changes: 5 additions & 0 deletions app/assets/stylesheets/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@
font-size: 18px;
}
}

label.required:after {
content: " *";
color: red;
}
50 changes: 50 additions & 0 deletions app/controllers/flows/newsletters_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# frozen_string_literal: true
class Flows::NewslettersController < ApplicationController
def index
@newsletters = current_user.newsletters.order(id: :asc)
end

def show
@newsletter = newsletter
# render "flows/#{params[:id]}"
end

def new
@newsletter = current_user.newsletters.build
end

def create
@newsletter = current_user.newsletters.build(newsletter_params)
if @newsletter.save
redirect_to flows_newsletters_path, notice: 'Newsletter has been created'
else
render :new
end
end

def update
@newsletter = newsletter
if @newsletter.update(newsletter_params)
redirect_to flows_newsletter_path(@newsletter), notice: 'Изменения сохранены'
else
render :show
end
end

def destroy
newsletter_name = newsletter.name
newsletter.destroy
redirect_to flows_newsletters_path,
notice: "Newsletter \"#{newsletter_name}\" has been deleted"
end

private

def newsletter
@_newsletter ||= current_user.newsletters.find(params[:id])
end

def newsletter_params
params.require(:newsletter).permit(:name, :description, :link)
end
end
11 changes: 11 additions & 0 deletions app/models/newsletter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true
class Newsletter < ApplicationRecord
acts_as_paranoid

belongs_to :owner, class_name: 'User', foreign_key: 'user_id'

validates :name, :description, presence: true
validates :name, length: { maximum: 255 }
validates :link, format: { with: %r{\Ahttps?:\/\/+}, message: 'Invalid url format' },
allow_blank: true
end
5 changes: 4 additions & 1 deletion app/models/user.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# frozen_string_literal: true
class User < ApplicationRecord
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
devise :database_authenticatable, :registerable, :recoverable, :rememberable,
:trackable, :validatable

has_many :newsletters

validates :name, presence: true, length: { maximum: 255 }
end
File renamed without changes.
13 changes: 13 additions & 0 deletions app/views/flows/newsletters/_contacts.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.col-lg-3.col-lg-offset-1
.form-group
label Поиск контактов
input type="search" value="E-mail - автокомплит добавление" class="form-control"

.form-group
label Подписчики
ul
- %w(Николай Иван Федор Джон Илья Стивен).each do |name|
li
= link_to name, flow_path(id: 'contact')
.pull-right
= link_to 'X', '#delete', class: 'label label-danger'
20 changes: 20 additions & 0 deletions app/views/flows/newsletters/_form.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
= form_for newsletter, url: url, html: { class: 'for-horizontal' } do |f|
.row
= render 'shared/errors', model: newsletter
.col-lg-8
.form-group
= f.label :name, value: 'Заголовок', class: 'required'
= f.text_field :name, class: 'form-control'
.form-group
= f.label :description, class: 'required',
value: 'Описание (Визуальный редактор MarkitUp например)'
= f.text_area :description, rows: '10', class: 'form-control'
.form-group
= f.label :link, value: 'Публичная ссылка для подписки'
= f.text_field :link, class: 'form-control'

- if show_contacts
= render 'contacts'
.row
.form-group
button class="btn btn-success" Сохранить
7 changes: 7 additions & 0 deletions app/views/flows/newsletters/_newsletter.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
tr
td= newsletter.id
td= newsletter.created_at.strftime('%Y-%m-%d')
td= link_to newsletter.name, flows_newsletter_path(newsletter)
td.text-center= rand(100)
td.text-center= rand(100)
td.text-center= rand(10)
16 changes: 16 additions & 0 deletions app/views/flows/newsletters/index.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
h1 Мои рассылки

.form-group
= link_to '+ Создать рассылку', new_flows_newsletter_path, class: 'btn btn-primary'
- unless @newsletters.present?
.alert.alert-warning.text-center Нет созданных рассылок
- else
table.table.table-striped.table-hover
tr
th ID
th Дата
th Название
th Кол-во подписчиков
th Кол-во отписавшихся
th Кол-во E-mail рассылок
= render @newsletters
3 changes: 3 additions & 0 deletions app/views/flows/newsletters/new.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
h1 Создать рассылку
= render 'form', newsletter: @newsletter, url: flows_newsletters_path,
show_contacts: false
31 changes: 31 additions & 0 deletions app/views/flows/newsletters/show.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
h1.pull-left Рассылка - #{@newsletter.name}
= button_to 'Destroy', flows_newsletter_path(@newsletter), method: :delete,
class: 'btn btn-md btn-danger pull-right', data: { confirm: 'Are you sure ?' }

= render 'form', newsletter: @newsletter, url: flows_newsletter_path,
show_contacts: true
.row
.panel.panel-default
.panel-heading Письма
.panel-body
table.table-striped.table-hover.table
tr
th ID
th Заголовок
th Дата создания
th Кол-во отправленных писем
th Ошибка доставки
tr
td 101
td= link_to '%{user_name} послушай Сезоны Вивальди', flow_path(id: :email)
td 20-06-2016
td.text-success.text-center 100
td.text-danger.text-center 5
tr
td 100
td= link_to '%{user_name} послушай Сезоны Вивальди', flow_path(id: :email)
td 20-06-2016
td.text-success.text-center 182
td.text-danger.text-center 2


7 changes: 7 additions & 0 deletions app/views/shared/_errors.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.col-md-12
- if model.errors.any?
#error_explanation
h2 #{pluralize(model.errors.count, 'error')} prohibited this #{model.class.name} from being saved:
ul
- model.errors.full_messages.each do |msg|
li= msg
3 changes: 3 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
Rails.application.routes.draw do
devise_for :users
namespace :flows do
resources :newsletters, except: [:edit]
end
resources :flows, only: [:index, :show]
root to: 'flows#index'
end
11 changes: 11 additions & 0 deletions db/migrate/20160914125745_create_newsletters.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class CreateNewsletters < ActiveRecord::Migration[5.0]
def change
create_table :newsletters do |t|
t.string :name
t.text :description
t.string :link

t.timestamps
end
end
end
5 changes: 5 additions & 0 deletions db/migrate/20160915201638_add_owner_id_to_newsletters.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddOwnerIdToNewsletters < ActiveRecord::Migration[5.0]
def change
add_reference :newsletters, :user, foreign_key: true, index: true
end
end
6 changes: 6 additions & 0 deletions db/migrate/20160917063337_add_deleted_at_to_newsletters.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class AddDeletedAtToNewsletters < ActiveRecord::Migration[5.0]
def change
add_column :newsletters, :deleted_at, :datetime
add_index :newsletters, :deleted_at
end
end
9 changes: 9 additions & 0 deletions db/migrate/20160917154110_add_limit_name_to_newsletters.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class AddLimitNameToNewsletters < ActiveRecord::Migration[5.0]
def up
change_column :newsletters, :name, :string, limit: 255
end

def down
change_column :newsletters, :name, :string
end
end
9 changes: 9 additions & 0 deletions db/migrate/20160917154254_add_limit_name_to_users.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class AddLimitNameToUsers < ActiveRecord::Migration[5.0]
def up
change_column :users, :name, :string, limit: 255
end

def down
change_column :users, :name, :string
end
end
15 changes: 14 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,19 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20160901135051) do
ActiveRecord::Schema.define(version: 20160917154254) do

create_table "newsletters", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
t.string "name"
t.text "description", limit: 65535
t.string "link"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
t.datetime "deleted_at"
t.index ["deleted_at"], name: "index_newsletters_on_deleted_at", using: :btree
t.index ["user_id"], name: "index_newsletters_on_user_id", using: :btree
end

create_table "users", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
t.string "email", default: "", null: false
Expand All @@ -30,4 +42,5 @@
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
end

add_foreign_key "newsletters", "users"
end
7 changes: 7 additions & 0 deletions spec/controllers/newsletters_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true
# describe Flows::NewslettersController, type: :controller do
# describe 'GET #index' do
# xit 'renders template' do
# end
# end
# end
8 changes: 8 additions & 0 deletions spec/factories/newsletter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true
FactoryGirl.define do
factory :newsletter do
name { Faker::Name.title }
description { Faker::Lorem.paragraph(4) }
link { Faker::Internet.url }
end
end
14 changes: 14 additions & 0 deletions spec/models/newsletter_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true
RSpec.describe Newsletter, type: :model do
subject { FactoryGirl.build(:newsletter) }

it { should belong_to(:owner).class_name('User') }

context 'with validation' do
it { should validate_presence_of(:name) }
it { should validate_presence_of(:description) }
it { should validate_length_of(:name).is_at_most(255) }
it { should allow_value('http://foo.com').for(:link) }
it { should_not allow_value('http:foo.com').for(:link) }
end
end
14 changes: 10 additions & 4 deletions spec/models/user_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,31 @@
it 'checks empty name' do
subject.name = nil
subject.valid?
expect(subject.errors[:name].count).to be > 0
expect(subject.errors[:name].count).to be_positive
end

it 'check length of name' do
subject.name = 'Astrum' * 100
subject.valid?
expect(subject.errors[:name].count).to be > 0
expect(subject.errors[:name].count).to be_positive
end

it 'checks empty email' do
subject.email = nil
subject.valid?
expect(subject.errors[:email].count).to be > 0
expect(subject.errors[:email].count).to be_positive
end

it 'checks uniqueness of email' do
FactoryGirl.create(:user, name: subject.name, email: subject.email, password: subject.password)
subject.valid?
expect(subject.errors[:email].count).to be > 0
expect(subject.errors[:email].count).to be_positive
end
end

context 'association' do
it 'responds to newsletters association' do
expect(subject).to respond_to(:newsletters)
end
end
end
7 changes: 7 additions & 0 deletions spec/rails_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,10 @@

config.include FactoryGirl::Syntax::Methods
end

Shoulda::Matchers.configure do |config|
config.integrate do |with|
with.test_framework :rspec
with.library :rails
end
end

0 comments on commit 25736b6

Please sign in to comment.