如何对一张照片进行投票并自动对另一张照片进行投票?
How to upvote a photo and automatically downvote the other photo?
我有一个显示 2 张随机照片的竞赛模型的显示视图:
<% if @contest.photos.size < 2 %>
<p>not enough photos in this contest</p>
<% else %>
<%= link_to (image_tag @random_photo1.image.url(:thumb)), upvote_path(id: @contest.id, photo_id: @random_photo1.id) %>
<%= @random_photo1.score %>
<%= link_to (image_tag @random_photo2.image.url(:thumb)), "#" %>
<%= @random_photo2.score %>
<% end %>
这是我的表演动作:
def show
@contest = Contest.find(params[:id])
@user = current_user
random_two_photos = @contest.photos.limit(2).order("RANDOM()")
@random_photo1 = random_two_photos[0]
@random_photo2 = random_two_photos[1]
end
这是我的 2 个动作的路线:
get 'contest/:id/photo/:photo_id' => 'contests#enter_contest', as: :enter_contest
get 'contest/:id/photo/:photo_id' => 'contests#upvote', as: :upvote
如何编写 "upvote" 控制器动作,使我点击的照片获得 100 分,而另一张照片获得 -100 分?我正在使用 postgresql。
我会使用其他路线:
get 'contests/:id/start' => 'contests#start', as: start_contest
put 'contests/:id/vote' => 'contests#vote', as: vote
然后,在contests_controller/start动作中
def start
@contest = Contest.find(params[:id])
random_photos = @contest.photos.limit(2).order("RANDOM()")
@photo1 = random_photos.first
@photo2 = random_photos.last
end
在contests_controller/start行动中
def vote
@contest = Contest.find(params[:id])
@photo1 = Photo.find(params[:up_photo_id])
@photo2 = Photo.find(params[:down_photo_id])
@photo1.upvote # you need to put this method in Photo model
@photo2.downvote # you need to put this method in the Photo model
end
在contests/start视图中:
<%= link_to image_tag(@photo1.image.url(:thumb)), vote_path(id: @contest.id, up_photo_id: @photo1.id, down_photo_id: @photo2.id) %>
和...
<%= link_to image_tag(@photo2.image.url(:thumb)), vote_path(id: @contest.id, up_photo_id: @photo2.id, down_photo_id: @photo1.id) %>
Remember: you need to pass the option method: :put
to link_to helper in order to perform a PUT instead a GET.
改进
- 您可以将代码放在 vote 动作中 Transaction. It's not a clean solution to put transactions in the controller layer. Maybe you can use the Service pattern
- 您可以将 "links to" 方法移动到视图助手。类似于:
vote_link(contest, up_photo, down_photo)
避免代码重复。
- 您可以将此:
photos.limit(2).order("RANDOM()")
移动到模型中的方法。类似于:@contest.random_photos(2)
The code I wrote was not tested. But you get the idea...
更新以使用单个表演动作
您需要定义一条路线
resources :contests, only: [:show]
然后在contests_controller/show动作
def show
@contest = Contest.find(params[:id])
if params.has_key? :up_photo_id && params.has_key? :down_photo_id
@photo1 = Photo.find(params[:up_photo_id])
@photo2 = Photo.find(params[:down_photo_id])
@photo1.upvote # you need to put this method in Photo model
@photo2.downvote # you need to put this method in the Photo model
else
random_photos = @contest.photos.limit(2).order("RANDOM()")
@photo1 = random_photos.first
@photo2 = random_photos.last
end
end
在show.html.erb
<%= link_to image_tag(@photo1.image.url(:thumb)), contest_path(id: @contest.id, up_photo_id: @photo1.id, down_photo_id: @photo2.id) %>
和...
<%= link_to image_tag(@photo2.image.url(:thumb)), contest_path(id: @contest.id, up_photo_id: @photo2.id, down_photo_id: @photo1.id) %>
更新:获取不同的照片
class Contest < ActiveRecord::Base
def random_photos
self.photos.order("RANDOM()")
end
def two_different_photos
photo1 = random_photos.first
raise 'no photos' unless photo1 # raise an exception or something
photo2 = random_photos.where.not(id: photo1.id).first
raise 'only one photo' unless photo2 # raise an exception or something
[photo1, photo2]
end
end
然后你可以在你的控制器中使用@contest.two_different_photos
...
我有一个显示 2 张随机照片的竞赛模型的显示视图:
<% if @contest.photos.size < 2 %>
<p>not enough photos in this contest</p>
<% else %>
<%= link_to (image_tag @random_photo1.image.url(:thumb)), upvote_path(id: @contest.id, photo_id: @random_photo1.id) %>
<%= @random_photo1.score %>
<%= link_to (image_tag @random_photo2.image.url(:thumb)), "#" %>
<%= @random_photo2.score %>
<% end %>
这是我的表演动作:
def show
@contest = Contest.find(params[:id])
@user = current_user
random_two_photos = @contest.photos.limit(2).order("RANDOM()")
@random_photo1 = random_two_photos[0]
@random_photo2 = random_two_photos[1]
end
这是我的 2 个动作的路线:
get 'contest/:id/photo/:photo_id' => 'contests#enter_contest', as: :enter_contest
get 'contest/:id/photo/:photo_id' => 'contests#upvote', as: :upvote
如何编写 "upvote" 控制器动作,使我点击的照片获得 100 分,而另一张照片获得 -100 分?我正在使用 postgresql。
我会使用其他路线:
get 'contests/:id/start' => 'contests#start', as: start_contest
put 'contests/:id/vote' => 'contests#vote', as: vote
然后,在contests_controller/start动作中
def start
@contest = Contest.find(params[:id])
random_photos = @contest.photos.limit(2).order("RANDOM()")
@photo1 = random_photos.first
@photo2 = random_photos.last
end
在contests_controller/start行动中
def vote
@contest = Contest.find(params[:id])
@photo1 = Photo.find(params[:up_photo_id])
@photo2 = Photo.find(params[:down_photo_id])
@photo1.upvote # you need to put this method in Photo model
@photo2.downvote # you need to put this method in the Photo model
end
在contests/start视图中:
<%= link_to image_tag(@photo1.image.url(:thumb)), vote_path(id: @contest.id, up_photo_id: @photo1.id, down_photo_id: @photo2.id) %>
和...
<%= link_to image_tag(@photo2.image.url(:thumb)), vote_path(id: @contest.id, up_photo_id: @photo2.id, down_photo_id: @photo1.id) %>
Remember: you need to pass the option
method: :put
to link_to helper in order to perform a PUT instead a GET.
改进
- 您可以将代码放在 vote 动作中 Transaction. It's not a clean solution to put transactions in the controller layer. Maybe you can use the Service pattern
- 您可以将 "links to" 方法移动到视图助手。类似于:
vote_link(contest, up_photo, down_photo)
避免代码重复。 - 您可以将此:
photos.limit(2).order("RANDOM()")
移动到模型中的方法。类似于:@contest.random_photos(2)
The code I wrote was not tested. But you get the idea...
更新以使用单个表演动作
您需要定义一条路线
resources :contests, only: [:show]
然后在contests_controller/show动作
def show
@contest = Contest.find(params[:id])
if params.has_key? :up_photo_id && params.has_key? :down_photo_id
@photo1 = Photo.find(params[:up_photo_id])
@photo2 = Photo.find(params[:down_photo_id])
@photo1.upvote # you need to put this method in Photo model
@photo2.downvote # you need to put this method in the Photo model
else
random_photos = @contest.photos.limit(2).order("RANDOM()")
@photo1 = random_photos.first
@photo2 = random_photos.last
end
end
在show.html.erb
<%= link_to image_tag(@photo1.image.url(:thumb)), contest_path(id: @contest.id, up_photo_id: @photo1.id, down_photo_id: @photo2.id) %>
和...
<%= link_to image_tag(@photo2.image.url(:thumb)), contest_path(id: @contest.id, up_photo_id: @photo2.id, down_photo_id: @photo1.id) %>
更新:获取不同的照片
class Contest < ActiveRecord::Base
def random_photos
self.photos.order("RANDOM()")
end
def two_different_photos
photo1 = random_photos.first
raise 'no photos' unless photo1 # raise an exception or something
photo2 = random_photos.where.not(id: photo1.id).first
raise 'only one photo' unless photo2 # raise an exception or something
[photo1, photo2]
end
end
然后你可以在你的控制器中使用@contest.two_different_photos
...