Reputation: 196
I would like to create relationships between three models: user, post and comment.
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:
user.rb
class User < ActiveRecord::Base has_many :posts has_many :comments end
post.rb
class Post < ActiveRecord::Base
belongs_to :user
has_many :comments
end
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.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
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.
Upvotes: 1
Views: 201
Reputation: 882
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...
Upvotes: 0
Reputation: 671
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
Upvotes: 0