0
votes

I would like to create relationships between three models: user, post and comment.

  1. User have many posts and comments
  2. Post have only one user and many comments
  3. Comment have one user and one post

so i create next migrations:

class Users < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :name
      t.string :email

      t.timestamps
    end
  end
end


class Posts < ActiveRecord::Migration
  def change
    create_table :posts do |t|
      t.string :content
      t.integer :user_id
      t.timestamps
    end  
  end
end



class Comments < ActiveRecord::Migration
  def change
    create_table :comments do |t|
      t.string :title
            t.string :content
      t.integer :user_id
            t.integer :post_id
      t.timestamps
    end  
  end
end

=============================================

models are next:

  1. user.rb

    class User < ActiveRecord::Base has_many :posts has_many :comments end

  2. post.rb

    class Post < ActiveRecord::Base belongs_to :user has_many :comments
    end

  3. comment.rb

    class Comment < ActiveRecord::Base belongs_to :user belongs_to :post
    end

===============================================

My users_controller.rb

class UsersController < ApplicationController
  before_action :signed_in_user, only: [:index, :edit, :update, :destroy]
  before_action :correct_user,   only: [:edit, :update]
  before_action :admin_user,     only: :destroy
  def index
    @users = User.paginate(page: params[:page])
  end


  def show
    @user = User.find(params[:id])
    @posts = @user.posts.paginate(page: params[:page])
        @comments = @user.comments.paginate(page: params[:page])  
    end

  def new
    @user = User.new(params[:user])
  end

  def edit
    #@user = User.find(params[:id])
  end

  def update
    #@user = User.find(params[:id])
      if @user.update_attributes(user_params)
        flash[:success] = "Profile updated"
        redirect_to @user
      else
        render 'edit'
      end
  end

  def destroy
    User.find(params[:id]).destroy
    flash[:success] = "User deleted."
    redirect_to users_url
  end

  def create
    @user = User.new(user_params)
      if @user.save
        flash[:success] = "Welcome to the Sample App!"
        redirect_to @user
      else
        render 'new'
      end
  end



  private

    def user_params
      params.require(:user).permit(:name, :email, :password,
                                   :password_confirmation)
    end

    # Before filters



    def correct_user
      @user = User.find(params[:id])
      redirect_to(root_url) unless current_user?(@user)
    end

    def admin_user
      redirect_to(root_url) unless current_user.admin?
    end
end

now i want to create some actions for next tasks:

  1. For posts_controller.rb

1.1 create a post by user 1.2 delete a post by user 1.3 show user post with all comments 1.4 show all user posts

class PostsController < ApplicationController
    before_action :signed_in_user, only: [:create, :destroy]
  before_action :correct_user,   only: :destroy


    def create 
        @post = user.post.build(post_params)
        @post = post.save
    end


    def destroy
        @post.destroy
    end

    def show_user_post_with_all_comments
        ???
    end

    def show_all_user_posts
        ??? 
    end


    private

    def post_params
      params.require(:post).permit(:title, :content)
    end

    def correct_user
      @post = current_user.posts.find_by(id: params[:id])
      redirect_to root_url if @post.nil?
    end
end
  1. For comments_controller.rb 2.1 create a comment by user in post 2.2 delete a comment by user in post 2.3 show all user comments
    2.4 find and show a post by user comment

    class CommentsController < ApplicationController before_action :signed_in_user, only: [:create, :destroy] before_action :correct_user, only: :destroy

    def create 
        @comment = user.comment.build(comment_params)
        @comment = comment.save
    end
    
    
    
    def destroy
        @comment.destroy
    end
    
    
    def show_comment
    ???
    end
    
    def show_all_user_comments  
    ??? 
    end
    
    def find_and_show_post_by_user_comment
    ??? 
    end 
    
    private
    
    def comment_params
      params.require(:comment).permit(:content)
    end
    
    def correct_user
      @comment = current_user.comments.find_by(id: params[:id])
      redirect_to root_url if @comment.nil?
    end
    

    end

Pls check for correct my migrations and models and help me with creating of actions with "???" in bodies Thank you much for your answers.

2

2 Answers

0
votes

PostsController

def show_user_post_with_all_comments
    @post = Post.find(params[:id]).eager_load(:comments)
end

def show_all_user_posts
    @posts = current_user.posts
end

CommentsController

def show_comment
    @comment = Comment.find(params[:id])
end

def show_all_user_comments  
    @comments = current_user.comments
end

def find_and_show_post_by_user_comment
    @comment = Comment.find(params[:id]).eager_load(:post)
    @post = @comment.post 
end 
0
votes

What I've done in the past in a similar situation would be to put all this work in the UsersController and add a few new actions to it:

class UsersController < ApplicationController
  ...
  def new_post
    @user = User.find(params[:id])
  end

  def create_post
    @user = User.find(params[:id])
    if @user.update_attributes user_post_params
      redirect_to somewhere_path
    else
      render 'new_post'
    end
  end

  def show_post
    @post = Post.find(params[:id])
    # Not sure how you are implementing sessions, but say you have current_user defined
    # for sessions, then your view could have a delete link conditional on 
    # @post.user_id == current_user.id
    @comments = @post.comments
  end

  def show_all_posts
    @user = User.find(params[:id])
    @posts = @user.posts
  end

  def new_comment
    @user = current_user
    @post = Post.find(params[:id])
  end

  def create_comment
    @user = current_user
    @post = Post.find(params[:id])
    @comment = Comment.new(comment_params)
    if @post.update_attributes comment_params
      @user.comments << @comment
      if @user.save
        redirect_to somewhere
      else
        render 'new_comment'
      end
    else
      render 'new_comment'
    end
  end

  def show_comments
    @user = User.find(params[:id])
    @comments = @user.comments
  end
  ...
  private
  def user_post_params
    params.require(:user).permit(:id, posts_attributes: [:title, :content])
  end

  def comment_params
    params.require(:post).permit(:id, comments_attributes: [:content, :user_id])
  end

In show_post.html.erb:

 <% if @post.user_id == current_user.id %>
   <%= link_to 'delete', post, method: :delete, data: { confirm: "you sure?" }
 <% end %> 

in your routes.rb:

get '/user/:id/new_post' => 'users#new_post', as: :user_new_post
put '/user/:id/create_post' => 'test_takers#create_post', as: :user_create_post

...and similar lines for the other actions.

Hopefully this can get you started...