diff --git a/Gemfile b/Gemfile index 084fc05..7597d1c 100644 --- a/Gemfile +++ b/Gemfile @@ -13,6 +13,7 @@ gem 'uglifier', '>= 1.3.0' gem 'jquery-rails' gem 'turbolinks' gem 'haml-rails', "~> 0.9" +gem 'actionview-encoded_mail_to' # gem 'rabl-rails', '~> 0.4.1' # gem 'jbuilder', '~> 2.0' diff --git a/Gemfile.lock b/Gemfile.lock index 619003c..92e8a04 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -20,6 +20,8 @@ GEM erubis (~> 2.7.0) rails-dom-testing (~> 1.0, >= 1.0.5) rails-html-sanitizer (~> 1.0, >= 1.0.2) + actionview-encoded_mail_to (1.0.7) + rails activejob (4.2.4) activesupport (= 4.2.4) globalid (>= 0.3.0) @@ -245,6 +247,7 @@ PLATFORMS ruby DEPENDENCIES + actionview-encoded_mail_to awesome_print bcrypt (~> 3.1.7) binding_of_caller diff --git a/app/controllers/parents_controller.rb b/app/controllers/parents_controller.rb index 85c9c45..573c3f3 100644 --- a/app/controllers/parents_controller.rb +++ b/app/controllers/parents_controller.rb @@ -5,14 +5,40 @@ class ParentsController < ApplicationController end def show - @parent = Person.just_parents.where(id: params[:id]) + @parent = Person.includes(:children).find_by_id(params[:id]) + @more_children = Child.not_related_to(@parent.id) end def new + @parent = Person.new + 3.times { @parent.children.build } end def add - ap params - redirect_to list_parents_path + @parent = Person.create add_parent_params + + if @parent.persisted? + redirect_to parent_path(@parent), notice: 'Success!' + return + else + render :new + end end + + def edit + @parent = Person.includes(:children).find_by_id(params[:id]) + @more_children = Child.all + end + + private + + def add_parent_params + params.require(:parent).permit( + :first_name, + :last_name, + :phone, + :email, + children_attributes: [:first_name, :last_name] + ) + end end diff --git a/app/controllers/relationships_controller.rb b/app/controllers/relationships_controller.rb new file mode 100644 index 0000000..f46a36e --- /dev/null +++ b/app/controllers/relationships_controller.rb @@ -0,0 +1,19 @@ +class RelationshipsController < ApplicationController + def add_child + parent = Person.find(params[:parent]) + child = Child.find(params[:child]) + + parent.parenthoods.create(child) + + redirect_to :back, notice: 'Child added to parent!' + end + + def del_child + parent = Person.find(params[:parent]) + child = Child.find(params[:child]) + + parent.parenthoods.find_by_child_id(child.id).destroy + + redirect_to :back, notice: 'Child removed from parent!' + end +end diff --git a/app/models/child.rb b/app/models/child.rb index 6ad0104..54c72d3 100644 --- a/app/models/child.rb +++ b/app/models/child.rb @@ -5,6 +5,17 @@ class Child < ActiveRecord::Base validates :first_name, presence: true validates :last_name, presence: true + scope :not_related_to, lambda { |parent_id| + joins("LEFT JOIN ( + SELECT child_id + FROM parenthoods + WHERE person_id = #{sanitize(parent_id)} + ) as s1 on s1.child_id = children.id") + .where("s1.child_id is null") + .order(:first_name, :last_name) + .uniq + } + def name "#{first_name} #{last_name}" end diff --git a/app/models/person.rb b/app/models/person.rb index 8ea50a6..f804d1e 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -1,10 +1,11 @@ class Person < ActiveRecord::Base has_many :parenthoods has_many :children, through: :parenthoods - accepts_nested_attributes_for :children + accepts_nested_attributes_for :children, reject_if: :all_blank validates :first_name, presence: true validates :last_name, presence: true + validates :phone, presence: true scope :with_name, lambda { |name| where("concat(first_name, ' ', last_name) RLIKE ?", name) diff --git a/app/views/parents/index.html.haml b/app/views/parents/index.html.haml index 0a182a0..a7af5d2 100644 --- a/app/views/parents/index.html.haml +++ b/app/views/parents/index.html.haml @@ -2,7 +2,9 @@ - @parents.each do |parent| %ul - %li #{parent.name} #{page_link(parent)} + %li + = link_to parent.name, parent_path(parent) + = page_link(parent) %li= number_to_phone parent.phone %li= mail_to parent.email %li Children: diff --git a/app/views/parents/new.html.haml b/app/views/parents/new.html.haml index 708381e..5381c12 100644 --- a/app/views/parents/new.html.haml +++ b/app/views/parents/new.html.haml @@ -1,6 +1,12 @@ %h2 Add a New Parent -= form_for :parent do |f| +- if @parent.errors.full_messages.any? + .errors + %h1 Uh oh! + - @parent.errors.full_messages.each do |e| + %p= e + += form_for @parent, as: :parent, url: add_parent_path do |f| = f.label :first_name = f.text_field :first_name @@ -14,12 +20,11 @@ = f.email_field :email %h3 Children: - - = fields_for :child do |child| - = child.label :first_name - = child.text_field :first_name - - = child.label :last_name - = child.text_field :last_name + = f.fields_for :children, @parent.children do |c| + %fieldset + = c.label :first_name + = c.text_field :first_name + = c.label :last_name + = c.text_field :last_name = f.submit diff --git a/app/views/parents/show.html.haml b/app/views/parents/show.html.haml index 878e1b1..47f066f 100644 --- a/app/views/parents/show.html.haml +++ b/app/views/parents/show.html.haml @@ -1,2 +1,21 @@ -%h2 Parent -= raw(ap @parent) +%h2= @parent.name +%p= link_to 'edit', edit_parent_path(@parent) +%p Email: #{mail_to(@parent.email, nil, encode: 'hex')} +%p Phone: #{number_to_phone @parent.phone} #{page_link(@parent)} + +- unless @parent.children.empty? + %p Children: + %ul + - @parent.children.each do |child| + %li + = child.name + = link_to 'remove', del_parenthood_path(@parent, child), {method: :delete} + +%p Add Child: +:ruby + select_options = options_from_collection_for_select(@more_children, :id, :name) + html_options = { + include_blank: false, + prompt: 'Add a child to parent' + } += select_tag(:child, select_options, html_options) diff --git a/config/routes.rb b/config/routes.rb index b62b2b3..fce61bc 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,9 +2,13 @@ Rails.application.routes.draw do get 'parents', to: 'parents#index', as: :list_parents get 'parents/new', to: 'parents#new', as: :new_parent post 'parents/new', to: 'parents#add', as: :add_parent + get 'parents/edit/:id', to: 'parents#edit', as: :edit_parent get 'parents/:id', to: 'parents#show', as: :parent post 'parents/:id', to: 'parents#update', as: :update_parent + post 'parenthood/:parent/:child', to: 'relationships#add_child', as: :add_parenthood + delete 'parenthood/:parent/:child', to: 'relationships#del_child', as: :del_parenthood + get 'children', to: 'children#index', as: :list_children get 'children/lookup', to: 'children#lookup', as: :lookup_child