簡體   English   中英

如何對一張照片進行投票並自動對另一張照片進行投票?

[英]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

然后,在Competitions_controller /開始操作

def start
  @contest = Contest.find(params[:id])
  random_photos = @contest.photos.limit(2).order("RANDOM()")
  @photo1 = random_photos.first
  @photo2 = random_photos.last
end

Competitions_controller /開始動作中

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

競賽/開始視圖中:

<%= 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) %>

記住:您需要將option method: :put傳遞給link_to helper,以便執行PUT而不是GET。

改進

  • 您可以將代碼放入Transaction的 表決動作中。 將事務放入控制器層不是一個干凈的解決方案。 也許您可以使用服務模式
  • 您可以將“鏈接到”方法移動到視圖助手。 諸如: vote_link(contest, up_photo, down_photo)可避免代碼重復。
  • 您可以將以下內容移動到模型中的方法: photos.limit(2).order("RANDOM()") 像: @contest.random_photos(2)

我編寫的代碼未經測試。 但是你明白了...

更新以使用單個顯示動作

您需要定義一條路線

resources :contests, only: [:show]

然后在Competitions_controller / show action中

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 ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM