更新时间:2023-02-25 11:42:02
我想出:
我创建了一个实例方法来使用 find_by来检索用户的电影评论
方法评论
模型:
class User< ActiveRecord :: Base
....
def movie_review(album)
Review.find_by(user_id:self,album_id:album)
end
end
设置回调时,此方法也派上用场:
class ReviewsController< ApplicationController
before_action:limit_review,only:[:new,:create]
....
private
def limit_review
user_review = current_user.movie_review(@movie)
如果user_review.present?
redirect_to edit_movie_review_path(@movie,user_review)
end
end
end
创建了一个帮助方法,用于显示编辑或创建的相关链接。非常感谢Austio和他的建议:
模块评论Helper
def create_or_edit_review_path(movie)
user_review = current_user.movie_review(movie)if user_signed_in?
如果user_signed_in? &安培;&安培; user_review.present?
link_to编辑评论,edit_movie_review_path(movie,user_review)
else
link_to写评论,new_movie_review_path
end
end
end
最后这是我在我的视图模板中调用帮助器:
....
<%= create_or_edit_review_path(@album)%>
I have my app setup where users can write reviews for a movie. What I'd like to do is limit the user to create only one review per movie. I've managed to accomplish this in my reviews controller as so:
class ReviewsController < ApplicationController
before_action :has_reviewed, only [:new]
....
def has_reviewed?
if Review.where(user_id: current_user.id, movie_id: @movie.id).any?
redirect_to movie_reviews_path
flash[:notice] = "You've already written a review for this movie."
end
end
end
Where I'm now having trouble is translating this same logic into my index view template with the helper methods of Devise and CanCanCan at my disposal.
<% if user_signed_in? && ... %> # current_user has already created a review for this movie
<%= link_to "Edit Review", edit_movie_review_path(@movie, review) %>
<% else %>
<%= link_to "Write a Review", new_movie_review_path %>
<% end %>
Also: Is there any way to improve the lookup in my has_reviewed? method? I feel like there's a better way to write it but can't determine the most appropriate fix.
Here's what I came up with:
I created an instance method to retrieve a user's movie review using the find_by
method on the Review
model:
class User < ActiveRecord::Base
....
def movie_review(album)
Review.find_by(user_id: self, album_id: album)
end
end
This method also comes in handy when setting up my callback:
class ReviewsController < ApplicationController
before_action :limit_review, only: [:new, :create]
....
private
def limit_review
user_review = current_user.movie_review(@movie)
if user_review.present?
redirect_to edit_movie_review_path(@movie, user_review)
end
end
end
Created a helper method for showing the appropriate link to edit or create a review. Big thanks to Austio and his suggestion:
module ReviewsHelper
def create_or_edit_review_path(movie)
user_review = current_user.movie_review(movie) if user_signed_in?
if user_signed_in? && user_review.present?
link_to "Edit review", edit_movie_review_path(movie, user_review)
else
link_to "Write a review", new_movie_review_path
end
end
end
And at last this is how I call the helper in my view template(s):
....
<%= create_or_edit_review_path(@album) %>