I have 3 models in my app - User, Post & Review. A user has_many :posts
, posts has_many :reviews
.
To make a post or to drop a review the user should be logged in.
class ReviewsController < ApplicationController
def new
@post = Post.find(params[:post_id])
@review = Review.new
end
def create
@post = Post.find(params[:post_id])
@review = @post.reviews
@review = current_user.reviews.build(comment_params)
if @review.save
flash[:success] = "Hurray!!"
redirect_to user_path(current_user)
else
flash.now[:danger] = "Hurray!!"
render 'new'
end
# @review = current_user.review.post.new(comment_params)
# @review.save
# flash[:success] = "Comment Posted succesfully"
# redirect_to user_path(current_user)
end
private
def comment_params
# params.require(:review).permit(:comment)
params.require(:reviews).permit(:comment)
end
end
View - Review#new
<div class="row">
<div class="col-md-offset-3 col-md-8">
<b> Add a review </b>
</div>
</div>
<%= form_for [@post, @review] do |r| %>
<div class="row">
<div class="col-md-offset-3 col-md-7">
<% render 'errors' %>
</div>
</div>
<div class="row">
<div class="col-md-offset-3 col-md-7">
<div class="form-group">
<%= r.label :comment %>
<%= r.text_area :comment, class: "form-control" %>
</div>
<%= r.submit "Add", class: "btn btn-primary btn-block" %>
</div>
</div>
<% end %>
Routes:
Rails.application.routes.draw do
# root 'posts#index'
root 'mains#home'
resources :users
resources :posts do
resources :reviews
end
# resources :reviews
resource :sessions, only: [:new, :create, :destroy]
resources :passwords, only: [:new, :create, :edit, :update]
end
Params from logs:
{"authenticity_token"=>"XunDfWighjQFYPmGOuIBMXIaiKzNM1BEDiU5
OU2DxvZAvBCP+ERzYSEI/eA/FYIiEPKjo32BX6vqZDm2fQmHrQ==",
"review"=> {"comment"=>"dsf"}, "commit"=>"Add", "post_id"=>"12"}
There is no user id anywhere. It is right to pass 'post_id' the way it is passing?
I hope I'm able able to explain the problem at least now.
You need to add user_id
to Review model and associate them. User has_many :reviews
and Review belongs_to :user
. Add migration with
def change
add_reference :reviews, :user, foreign_key: true
end
And change the controller
class ReviewsController < ApplicationController
def new
@post = Post.find(params[:post_id])
@review = @post.reviews.new
end
def create
@post = Post.find(params[:post_id])
@review = @post.reviews.build(review_params)
@review.user_id = current_user.id
if @review.save
flash[:success] = "Hurray!!"
redirect_to user_path(current_user)
else
flash.now[:danger] = "Hurray!!"
render 'new'
end
end
private
def review_params
params.require(:review).permit(:comment)
end
end
And yes, it is correct to pass post_id
to the controller