Я хотел бы использовать другие маршруты:
get 'contests/:id/start' => 'contests#start', as: start_contest
put 'contests/:id/vote' => 'contests#vote', as: vote
Затем в contests_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
В contests_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) %>
Помните: вам нужно передать опцию method: :put
в link_to помощник для того, чтобы выполнять PUT вместо этого GET.
Улучшение
- Вы можете поместить код внутри голосования действий внутри Transaction. Это не чистое решение для размещения транзакций на уровне контроллера. Возможно, вы можете использовать Service pattern
- Вы можете переместить метод «ссылки на» в помощник представления. Что-то вроде:
vote_link(contest, up_photo, down_photo)
, чтобы избежать повторения кода.
- Вы можете перемещать:
photos.limit(2).order("RANDOM()")
в метод в модель. Что-то вроде: @contest.random_photos(2)
Код я написал не был проверен. Но ты получил идею...
UPDATE использовать один SHOW МЕР
Вы должны определить один маршрут
resources :contests, only: [:show]
Тогда в contests_controller/показать Действие
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) %>
UPDATE: чтобы получить различные фотографии
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
в контроллере .. .
Большое вам спасибо! Я попробую это прямо сейчас. Просто любопытно, каково ваше краткое мнение о рейлах против средней стеки? – 2paws
Подожди, я немного смущен. В настоящее время две случайные фотографии показываются с помощью действия # show controller. Если я напишу конкурсные действия # start, разве это не повлияет на две случайные фотографии, которые не предназначены? – 2paws
О среднем ... У меня нет опыта с экспрессом или узлом, монго немного, и у меня есть опыт с угловым. Но тем не менее, я больше сторонник/рубиновый парень. Итак, у меня нет «полезного» мнения. Ваш второй вопрос: вы можете использовать действие show вместо действия «Пуск», если хотите. Если «начало действия» представляет конкурс, используйте шоу. Что вы имеете в виду: «конкурсы # начать действие, разве это не повлияло бы на две случайные фотографии, которые не предназначены?» – Leantraxxx