diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb
new file mode 100644
index 0000000..b20809d
--- /dev/null
+++ b/app/controllers/posts_controller.rb
@@ -0,0 +1,39 @@
+class PostsController < ApplicationController
+ before_action :require_authentication
+
+ def index
+ @post = Post.new
+ @posts = Post.all.order(created_at: :desc)
+ end
+
+ def create
+ @post = current_user.posts.new(post_params)
+
+ respond_to do |f|
+ if @post.save
+ format.turbo_stream
+ else
+ format.html do
+ flash[:post_errors] = @post.errors.full_messages
+ redirect_to root_path
+ end
+ end
+ end
+ end
+
+ def show
+ @post = Post.find(params[:id])
+ end
+
+ def destroy
+ @post = current_user.posts.find(params[:id])
+ @post.destroy
+ redirect_to root_path, notice: "Post has been successfully deleted."
+ end
+
+ private
+
+ def post_params
+ params.require(:post).permit(:body)
+ end
+end
diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb
new file mode 100644
index 0000000..448e189
--- /dev/null
+++ b/app/controllers/profiles_controller.rb
@@ -0,0 +1,25 @@
+class ProfilesController < ApplicationController
+ def show
+ @user = User.find_by(username: params[:username])
+ @tweets = @user.tweets.order(created_at: :desc)
+ end
+
+ def edit
+ @user = current_user
+ end
+
+ def update
+ @user = current_user
+ if @user.update(profile_params)
+ redirect_to profile_path(@user.username), notice: "Profile updated successfully"
+ else
+ render :edit
+ end
+ end
+
+ private
+
+ def profile_params
+ params.require(:user).permit(:name, :username, :bio)
+ end
+end
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
new file mode 100644
index 0000000..3e74dea
--- /dev/null
+++ b/app/controllers/users_controller.rb
@@ -0,0 +1,2 @@
+class UsersController < ApplicationController
+end
diff --git a/app/helpers/posts_helper.rb b/app/helpers/posts_helper.rb
new file mode 100644
index 0000000..a7b8cec
--- /dev/null
+++ b/app/helpers/posts_helper.rb
@@ -0,0 +1,2 @@
+module PostsHelper
+end
diff --git a/app/helpers/registrations_helper.rb b/app/helpers/registrations_helper.rb
new file mode 100644
index 0000000..b100376
--- /dev/null
+++ b/app/helpers/registrations_helper.rb
@@ -0,0 +1,2 @@
+module RegistrationsHelper
+end
diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb
new file mode 100644
index 0000000..2310a24
--- /dev/null
+++ b/app/helpers/users_helper.rb
@@ -0,0 +1,2 @@
+module UsersHelper
+end
diff --git a/app/models/post.rb b/app/models/post.rb
new file mode 100644
index 0000000..b028c5f
--- /dev/null
+++ b/app/models/post.rb
@@ -0,0 +1,5 @@
+class Post < ApplicationRecord
+ belongs_to :user
+
+ validates :content, presence: true, length: { maximum: 280 }
+end
diff --git a/app/models/relationship.rb b/app/models/relationship.rb
new file mode 100644
index 0000000..3cabc44
--- /dev/null
+++ b/app/models/relationship.rb
@@ -0,0 +1,2 @@
+class Relationship < ApplicationRecord
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index 626edbc..544f555 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1,6 +1,15 @@
class User < ApplicationRecord
has_secure_password
has_many :sessions, dependent: :destroy
+ has_many :posts, dependent: :destroy
+ has_many :active_relationships, class_name: "Relationship", foreign_key: "follower_id", dependent: :destroy
+ has_many :passive_relationships, class_name: "Relationship", foreign_key: "followed_id", dependent: :destroy
+ has_many :following, through: :active_relationships, source: :followed
+ has_many :followers, through: :passive_relationships, source: :follower
- normalizes :email_address, with: -> e { e.strip.downcase }
+ validates :username, presence: true, uniqueness: true
+ validates :first_name, presence: true
+ validates :last_name, presence: true
+ validates :email_address, presence: true, uniqueness: true
+ normalizes :email_address, with: ->(e) { e.strip.downcase }
end
diff --git a/app/views/profiles/edit.html.erb b/app/views/profiles/edit.html.erb
new file mode 100644
index 0000000..568cc64
--- /dev/null
+++ b/app/views/profiles/edit.html.erb
@@ -0,0 +1,14 @@
+
Edit Profile
+'
+<%= form_with(model: @user, url: profile_path, local: true) do |f| %>
+ <%= f.label :name %>
+ <%= f.text_field :name %>
+
+ <%= f.label :username %>
+ <%= f.text_field :username %>
+
+ <%= f.label :bio %>
+ <%= f.text_field :bio %>
+
+ <%= f.submit 'Update Profile' %>
+<% end %>
diff --git a/app/views/profiles/show.html.erb b/app/views/profiles/show.html.erb
new file mode 100644
index 0000000..429ab20
--- /dev/null
+++ b/app/views/profiles/show.html.erb
@@ -0,0 +1,9 @@
+<%= @user.first_name + @user.last_name %>
+<%= @user.username %>
+<%= @user.bio %>
+<% if current_user == @user %>
+ <%= link_to 'Edit Profile', edit_profile_path %>
+<% end %>
+
+
Posts
+<%= render @posts %>
diff --git a/config/routes.rb b/config/routes.rb
index 29b007b..b47710f 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -13,4 +13,7 @@
# Defines the root path route ("/")
# root "posts#index"
+ get "/:username", to: "profiles#show", as: :profile
+ get "/profile/edit", to: "profiles#edit", as: :edit_profile
+ post "/profile", to: "profiles#update"
end
diff --git a/db/migrate/20240928171644_create_users.rb b/db/migrate/20240928171644_create_users.rb
index 2075edf..5332431 100644
--- a/db/migrate/20240928171644_create_users.rb
+++ b/db/migrate/20240928171644_create_users.rb
@@ -1,9 +1,15 @@
class CreateUsers < ActiveRecord::Migration[8.0]
def change
create_table :users do |t|
+ t.string :username, null: false
+ t.string :first_name, null: false
+ t.string :last_name, null: false
+
t.string :email_address, null: false
t.string :password_digest, null: false
+ t.boolean :verified, null: false, default: false
+
t.timestamps
end
add_index :users, :email_address, unique: true
diff --git a/db/migrate/20240929121715_create_posts.rb b/db/migrate/20240929121715_create_posts.rb
new file mode 100644
index 0000000..b960f5a
--- /dev/null
+++ b/db/migrate/20240929121715_create_posts.rb
@@ -0,0 +1,10 @@
+class CreatePosts < ActiveRecord::Migration[8.0]
+ def change
+ create_table :posts do |t|
+ t.text :content
+ t.references :user, null: false, foreign_key: true
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/migrate/20240929125312_create_relationships.rb b/db/migrate/20240929125312_create_relationships.rb
new file mode 100644
index 0000000..0fc22c3
--- /dev/null
+++ b/db/migrate/20240929125312_create_relationships.rb
@@ -0,0 +1,10 @@
+class CreateRelationships < ActiveRecord::Migration[8.0]
+ def change
+ create_table :relationships do |t|
+ t.integer :follower_id
+ t.integer :followed_id
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/migrate/20240929184940_add_profile_fields_to_users.rb b/db/migrate/20240929184940_add_profile_fields_to_users.rb
new file mode 100644
index 0000000..543e9f3
--- /dev/null
+++ b/db/migrate/20240929184940_add_profile_fields_to_users.rb
@@ -0,0 +1,7 @@
+class AddProfileFieldsToUsers < ActiveRecord::Migration[8.0]
+ def change
+ add_column :users, :name, :string
+ add_column :users, :username, :string
+ add_column :users, :bio, :text
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
new file mode 100644
index 0000000..b2568df
--- /dev/null
+++ b/db/schema.rb
@@ -0,0 +1,48 @@
+# This file is auto-generated from the current state of the database. Instead
+# of editing this file, please use the migrations feature of Active Record to
+# incrementally modify your database, and then regenerate this schema definition.
+#
+# This file is the source Rails uses to define your schema when running `bin/rails
+# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
+# be faster and is potentially less error prone than running all of your
+# migrations from scratch. Old migrations may fail to apply correctly if those
+# migrations use external dependencies or application code.
+#
+# It's strongly recommended that you check this file into your version control system.
+
+ActiveRecord::Schema[8.0].define(version: 2024_09_29_125312) do
+ create_table "posts", force: :cascade do |t|
+ t.text "content"
+ t.integer "user_id", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["user_id"], name: "index_posts_on_user_id"
+ end
+
+ create_table "relationships", force: :cascade do |t|
+ t.integer "follower_id"
+ t.integer "followed_id"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ end
+
+ create_table "sessions", force: :cascade do |t|
+ t.integer "user_id", null: false
+ t.string "ip_address"
+ t.string "user_agent"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["user_id"], name: "index_sessions_on_user_id"
+ end
+
+ create_table "users", force: :cascade do |t|
+ t.string "email_address", null: false
+ t.string "password_digest", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["email_address"], name: "index_users_on_email_address", unique: true
+ end
+
+ add_foreign_key "posts", "users"
+ add_foreign_key "sessions", "users"
+end
diff --git a/test/controllers/posts_controller_test.rb b/test/controllers/posts_controller_test.rb
new file mode 100644
index 0000000..9034df0
--- /dev/null
+++ b/test/controllers/posts_controller_test.rb
@@ -0,0 +1,7 @@
+require "test_helper"
+
+class PostsControllerTest < ActionDispatch::IntegrationTest
+ # test "the truth" do
+ # assert true
+ # end
+end
diff --git a/test/controllers/registrations_controller_test.rb b/test/controllers/registrations_controller_test.rb
new file mode 100644
index 0000000..b5b7c37
--- /dev/null
+++ b/test/controllers/registrations_controller_test.rb
@@ -0,0 +1,7 @@
+require "test_helper"
+
+class RegistrationsControllerTest < ActionDispatch::IntegrationTest
+ # test "the truth" do
+ # assert true
+ # end
+end
diff --git a/test/controllers/users_controller_test.rb b/test/controllers/users_controller_test.rb
new file mode 100644
index 0000000..61c1532
--- /dev/null
+++ b/test/controllers/users_controller_test.rb
@@ -0,0 +1,7 @@
+require "test_helper"
+
+class UsersControllerTest < ActionDispatch::IntegrationTest
+ # test "the truth" do
+ # assert true
+ # end
+end
diff --git a/test/fixtures/posts.yml b/test/fixtures/posts.yml
new file mode 100644
index 0000000..33f7a30
--- /dev/null
+++ b/test/fixtures/posts.yml
@@ -0,0 +1,9 @@
+# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+one:
+ content: MyText
+ user: one
+
+two:
+ content: MyText
+ user: two
diff --git a/test/fixtures/relationships.yml b/test/fixtures/relationships.yml
new file mode 100644
index 0000000..d70987c
--- /dev/null
+++ b/test/fixtures/relationships.yml
@@ -0,0 +1,9 @@
+# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+one:
+ follower_id: 1
+ followed_id: 1
+
+two:
+ follower_id: 1
+ followed_id: 1
diff --git a/test/models/post_test.rb b/test/models/post_test.rb
new file mode 100644
index 0000000..ff155c4
--- /dev/null
+++ b/test/models/post_test.rb
@@ -0,0 +1,7 @@
+require "test_helper"
+
+class PostTest < ActiveSupport::TestCase
+ # test "the truth" do
+ # assert true
+ # end
+end
diff --git a/test/models/relationship_test.rb b/test/models/relationship_test.rb
new file mode 100644
index 0000000..6b1491a
--- /dev/null
+++ b/test/models/relationship_test.rb
@@ -0,0 +1,7 @@
+require "test_helper"
+
+class RelationshipTest < ActiveSupport::TestCase
+ # test "the truth" do
+ # assert true
+ # end
+end