Ver código fonte

Add metadata to User profiles

Frans Bergman 7 anos atrás
pai
commit
149731a77f

+ 8 - 0
app/assets/stylesheets/users.scss

@@ -6,4 +6,12 @@
   h1 {
     font-size: 2em;
   }
+
+  ul {
+    padding-left: 0;
+    li {
+      list-style: none;
+      font-size: 1.1em;
+    }
+  }
 }

+ 10 - 0
app/helpers/users_helper.rb

@@ -1,2 +1,12 @@
 module UsersHelper
+  def age_in_completed_years (bd)
+    # Difference in years, less one if you have not had a birthday this year.
+    d = Date.today.year
+    a = d - bd.year
+    a = a - 1 if (
+         bd.month >  d.month or
+        (bd.month >= d.month and bd.day > d.day)
+    )
+    a
+  end
 end

+ 10 - 1
app/models/user.rb

@@ -1,7 +1,7 @@
 class User < ApplicationRecord
   attr_accessor :remember_token
 
-  validates :name, presence: true
+  validates :name, presence: true, length: { maximum: 255 }
 
   VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
   validates :email, presence: true, length: { maximum: 255 },
@@ -16,6 +16,15 @@ class User < ApplicationRecord
   has_secure_password
   validates :password, presence: true, length: { minimum: 6 }
 
+  enum gender: [ :unspecified, :male, :female, :other ]
+
+  VALID_PHONE_REGEX = /[0-9a-z\-+() .]*/i
+  validates :phone, length: { maximum: 255 },
+                    format: { with: VALID_PHONE_REGEX }
+
+  validates :birth_date, presence: true
+
+
   # Returns the hash digest of the given string.
   def User.digest(string)
     cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :

+ 14 - 0
app/views/users/show.html.erb

@@ -5,6 +5,20 @@
       <h1>
         <%= @user.name %>
       </h1>
+      <ul>
+        <li class="user-gender">
+          Gender: <%= @user.gender.capitalize %>
+        </li>
+        <li class="user-age">
+          Age: <%= age_in_completed_years @user.birth_date %> years
+        </li>
+        <li class="user-email">
+          <%=  link_to fa_icon("envelope fw", text: @user.email), "mailto:#{@user.email}" %>
+        </li>
+        <li class="user-phone">
+          <%= fa_icon("phone fw", text: @user.phone) %>
+        </li>
+      </ul>
     </section>
   </aside>
 </div>

+ 7 - 0
db/migrate/20171220141141_add_meta_fields_to_users.rb

@@ -0,0 +1,7 @@
+class AddMetaFieldsToUsers < ActiveRecord::Migration[5.1]
+  def change
+    add_column :users, :gender, :integer, default: 0
+    add_column :users, :phone, :string
+    add_column :users, :birth_date, :date
+  end
+end

+ 4 - 1
db/schema.rb

@@ -10,7 +10,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema.define(version: 20171217153703) do
+ActiveRecord::Schema.define(version: 20171220141141) do
 
   create_table "users", force: :cascade do |t|
     t.string "name"
@@ -20,6 +20,9 @@ ActiveRecord::Schema.define(version: 20171217153703) do
     t.datetime "updated_at", null: false
     t.string "password_digest"
     t.string "remember_digest"
+    t.integer "gender", default: 0
+    t.string "phone"
+    t.date "birth_date"
     t.index ["login"], name: "index_users_on_login", unique: true
   end
 

+ 8 - 2
db/seeds.rb

@@ -10,7 +10,9 @@ User.create!(name:  "Example User",
              login: "example",
              email: "example@example.com",
              password:              "foobar",
-             password_confirmation: "foobar")
+             password_confirmation: "foobar",
+             birth_date: 15.years.ago,
+             phone:      "(333) 333-3333")
 
 
 99.times do |n|
@@ -18,9 +20,13 @@ User.create!(name:  "Example User",
  email = "example-#{n+1}@example.com"
  password = "password"
  login = "example_#{n+1}"
+ birth_date = Faker::Date.between(15.years.ago, 70.years.ago)
+ phone = Faker::PhoneNumber.cell_phone
  User.create!(name:  name,
               email: email,
               login: login,
               password:              password,
-              password_confirmation: password)
+              password_confirmation: password,
+              birth_date: birth_date,
+              phone:      phone)
 end

+ 8 - 0
test/controllers/users_controller_test.rb

@@ -1,5 +1,13 @@
 require 'test_helper'
 
 class UsersControllerTest < ActionDispatch::IntegrationTest
+  def setup
+    @user = users(:daniel)
+    log_in_as @user
+  end
 
+  test "should display age correctly" do
+    get user_path @user
+    assert_select ".user-age", /[A-z]+\: [0-9]+/
+  end
 end

+ 2 - 0
test/fixtures/users.yml

@@ -5,9 +5,11 @@ daniel:
   name: Daniel Smith
   email: daniel.smith@example.com
   password_digest: <%= User.digest('password') %>
+  birth_date: <%= 27.years.ago %>
 
 ben:
   login: ben_4321
   name: Ben Jones
   email: ben.jones@example.com
   password_digest: <%= User.digest('password') %>
+  birth_date: <%= 29.years.ago %>

+ 25 - 1
test/models/user_test.rb

@@ -4,7 +4,8 @@ class UserTest < ActiveSupport::TestCase
   def setup
     @user = User.new(login: "example", name: "Example User",
                      email: "user@example.com",
-                     password: "foobar", password_confirmation: "foobar")
+                     password: "foobar", password_confirmation: "foobar",
+                     birth_date: 30.years.ago)
   end
 
   test "should be valid" do
@@ -36,6 +37,11 @@ class UserTest < ActiveSupport::TestCase
     assert_not @user.valid?
   end
 
+  test "name should not be too long" do
+    @user.name = "a" * 256
+    assert_not @user.valid?
+  end
+
   test "email validation should accept valid addresses" do
     valid_addresses = %w[user@example.com USER@foo.COM A_US-ER@foo.bar.org
                          first.last@foo.jp alice+bob@baz.cn]
@@ -70,6 +76,24 @@ class UserTest < ActiveSupport::TestCase
     end
   end
 
+  test "phone number validation should accept valid phone number" do
+    valid_numbers = [
+      "333-333-3333",
+      "(333) 333-3333",
+      "1-333-333-3333",
+      "333.333.3333",
+      "333-333-3333",
+      "333-333-3333 x3333",
+      "(333) 333-3333 x3333",
+      "1-333-333-3333 x3333",
+      "333.333.3333 x3333",
+    ]
+    valid_numbers.each do |valid_number|
+      @user.phone = valid_number
+      assert @user.valid?, "#{valid_number.inspect} should be valid"
+    end
+  end
+
   test "login should be unique" do
     duplicate_user = @user.dup
     duplicate_user.email = "foo@bar.com"