-
Notifications
You must be signed in to change notification settings - Fork 1
Contacts #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Contacts #5
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -45,3 +45,5 @@ bower.json | |
| *.swp | ||
| *.swo | ||
| .vimrc | ||
|
|
||
| config/database.yml | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,3 +16,11 @@ label.required:after { | |
| content: " *"; | ||
| color: red; | ||
| } | ||
|
|
||
| .form-inline { | ||
| .form-group { | ||
| input { | ||
| width: 100%; | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # frozen_string_literal: true | ||
| class Flows::ContactsController < ApplicationController | ||
| def index | ||
| @contacts = contacts | ||
| @contact = current_user.contacts.build | ||
| end | ||
|
|
||
| def create | ||
| contact = Contact.find_or_initialize_by(email: contact_params[:email]) | ||
| contact.name = contact_params[:name] | ||
|
|
||
| if contact.save | ||
| membership = current_user.memberships.build(contact_id: contact.id) | ||
| return redirect_to flows_contacts_path, alert: 'Contact has already been added' unless membership.valid? | ||
| membership.save | ||
| redirect_to flows_contacts_path, notice: 'Contact has been added' | ||
| else | ||
| @contacts = contacts | ||
| @contact = contact | ||
| render :index | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. не очень нравится, как сделал сохранение. Тут две операции: добавляем контакт, создаем связь. Это две разные модели, у каждой есть своя валидация. Кстати, еще вопрос: в базе есть контакт
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mpakus понял, сервис попробую сделать. |
||
| end | ||
| end | ||
|
|
||
| def edit; end | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Редактирование нужно, пока не совсем понятны такие моменты:
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ничего страшного, agile и подразумевается, что запустил некую фичу за какой-то определенный период (спринт), пошел отзыв, что-то не понравилось переделал, это всегда можно сделать например хранить имена в Membership |
||
|
|
||
| def destroy; end | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Будем удалять только саму связь из memberships |
||
|
|
||
| private | ||
|
|
||
| def contacts | ||
| @contacts = current_user.contacts.order(id: :asc) | ||
| end | ||
|
|
||
| def contact_params | ||
| params.require(:contact).permit(:name, :email) | ||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| # frozen_string_literal: true | ||
| class Membership < ApplicationRecord | ||
| belongs_to :subscriber, class_name: 'User' | ||
| belongs_to :subscribed, class_name: 'User' | ||
|
|
||
| validates :name, presence: true, length: { maximum: 255 } | ||
| validates :subscribed_id, uniqueness: { scope: :subscriber_id } | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,13 @@ | ||
| # 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 | ||
| has_many :ownerships, class_name: 'Membership', foreign_key: :subscriber_id | ||
| has_many :memberships, foreign_key: :subscribed_id | ||
|
|
||
| has_many :subscribers, class_name: 'User', through: :memberships, foreign_key: :subscriber_id, dependent: :destroy | ||
| has_many :subscribeds, class_name: 'User', through: :ownerships, foreign_key: :subscribed_id, dependent: :destroy | ||
|
|
||
| validates :name, presence: true, length: { maximum: 255 } | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| tr | ||
| td= contact.id | ||
| td= link_to contact.name, '#' | ||
| td= contact.email | ||
| td= 0 | ||
| td= 0 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| .panel.panel-success | ||
| .panel-body | ||
| form.form-inline | ||
| = form_for contact, url: url, html: { class: 'for-inline' } do |f| | ||
| = render 'shared/errors', model: contact | ||
| .form-group.col-lg-5 | ||
| = f.text_field :name, placeholder: 'Name', class: 'form-control' | ||
| .form-group.col-lg-5 | ||
| = f.text_field :email, placeholder: 'E-mail', class: 'form-control' | ||
| .form-group.col-lg-2 | ||
| = f.submit 'Добавить', class: 'btn btn-success' |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| h1 Мои Контакты | ||
|
|
||
| = render 'form', contact: @contact, url: flows_contacts_path | ||
|
|
||
| - if @contacts.empty? | ||
| .alert.alert-warning.text-center Нет добавленных контактов | ||
| -else | ||
| table.table.table-hover.table-striped | ||
| tr | ||
| th ID | ||
| th Имя | ||
| th E-mail | ||
| th Кол-во подписок | ||
| th Кол-во отписанных | ||
| = render @contacts |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| class CreateUsersContacts < ActiveRecord::Migration[5.0] | ||
| def change | ||
| create_table :users_contacts, id: false do |t| | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Тут глобальная проблема эти join_table нужно называть в порядке отсортированных моделей соединяемых, тогда не надо будет явно указывать join_table http://guides.rubyonrails.org/association_basics.html#updating-the-schema
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. точно, не обратил внимания |
||
| t.belongs_to :user, index: true | ||
| t.belongs_to :contact, index: true | ||
| end | ||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| class CreateMemberships < ActiveRecord::Migration[5.0] | ||
| def change | ||
| create_table :memberships do |t| | ||
| t.belongs_to :user, index: true | ||
| t.belongs_to :contact, index: true | ||
|
|
||
| t.timestamps | ||
| end | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| class DropUsersContactsTable < ActiveRecord::Migration[5.0] | ||
| def change | ||
| drop_table :users_contacts, id: false do |t| | ||
| t.belongs_to :user, index: true | ||
| t.belongs_to :contact, index: true | ||
| end | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| class AddUniqueIndexToMemberships < ActiveRecord::Migration[5.0] | ||
| def change | ||
| add_index :memberships, [:user_id, :contact_id], unique: true | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| class AddNameToMemberships < ActiveRecord::Migration[5.0] | ||
| def change | ||
| add_column :memberships, :name, :string, limit: 255 | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| class RenameColumnsInMembership < ActiveRecord::Migration[5.0] | ||
| def change | ||
| rename_column :memberships, :user_id, :subscriber_id | ||
| rename_column :memberships, :contact_id, :subscribed_id | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,7 +10,18 @@ | |
| # | ||
| # It's strongly recommended that you check this file into your version control system. | ||
|
|
||
| ActiveRecord::Schema.define(version: 20160917154254) do | ||
| ActiveRecord::Schema.define(version: 20161004163616) do | ||
|
|
||
| create_table "memberships", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t| | ||
| t.integer "subscriber_id" | ||
| t.integer "subscribed_id" | ||
| t.datetime "created_at", null: false | ||
| t.datetime "updated_at", null: false | ||
| t.string "name" | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mpakus Добавил name |
||
| t.index ["subscribed_id"], name: "index_memberships_on_subscribed_id", using: :btree | ||
| t.index ["subscriber_id", "subscribed_id"], name: "index_memberships_on_subscriber_id_and_subscribed_id", unique: true, using: :btree | ||
| t.index ["subscriber_id"], name: "index_memberships_on_subscriber_id", using: :btree | ||
| end | ||
|
|
||
| create_table "newsletters", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t| | ||
| t.string "name" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| # frozen_string_literal: true | ||
| FactoryGirl.define do | ||
| factory :membership do | ||
| name { Faker::Name.name } | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| # frozen_string_literal: true | ||
| RSpec.describe Membership, type: :model do | ||
| subject { FactoryGirl.build(:membership) } | ||
|
|
||
| let(:batman){ FactoryGirl.create(:user, name: 'Batman') } | ||
| let(:catwoman){ FactoryGirl.create(:user, name: 'Catwoman') } | ||
| let(:spiderman){ FactoryGirl.create(:user, name: 'spiderman') } | ||
|
|
||
| context 'with relations' do | ||
| it { should belong_to(:subscriber) } | ||
| it { should belong_to(:subscribed) } | ||
| end | ||
|
|
||
| context 'with validations' do | ||
| before do | ||
| subject.subscriber = batman | ||
| subject.subscribed = catwoman | ||
| subject.save | ||
| end | ||
|
|
||
| it { should validate_presence_of(:name) } | ||
| it { should validate_length_of(:name).is_at_most(255) } | ||
|
|
||
| it 'subscribed user should be uniq for subscriber' do | ||
| should validate_uniqueness_of(:subscribed_id).scoped_to(:subscriber_id) | ||
| end | ||
| end | ||
|
|
||
| context 'with membership subscriptions' do | ||
| before do | ||
| subject.subscriber = batman | ||
| subject.subscribed = catwoman | ||
| subject.save | ||
| end | ||
|
|
||
| it 'subscribe 1 person' do | ||
| expect(Membership.count).to eq 1 | ||
| end | ||
|
|
||
| it 'subscribe 2 people' do | ||
| meme = FactoryGirl.build(:membership) | ||
| meme.subscriber = batman | ||
| meme.subscribed = spiderman | ||
| meme.save | ||
|
|
||
| expect(Membership.count).to eq 2 | ||
| end | ||
| end | ||
| end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
чтобы из Vim можно было запускать тесты