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