find_by_or_initialize_by * _and_ * и увеличение! - PullRequest
0 голосов
/ 08 апреля 2011

Я немного медлителен в программировании, но мне это нравится, и я стараюсь учиться как можно больше.Поэтому заранее извиняюсь, если я не достаточно ясно со своим вопросом.

У меня есть приложение, предназначенное исключительно для диджеев для просмотра песен и обзоров песен для группировки по штатам.5 полей:На 3 вопроса, на которые даны ответы в масштабе от 1 до 5, форма собирает 3 ответа, а также состояние пользователя и идентификатор песни.В большинстве случаев база данных просто находит состояние и идентификатор песни, а затем добавляет новые данные в 3 поля вопроса (djlike, thinkclublike, жгут).Но первый отзыв на песню от пользователя в новом состоянии должен будет создать новую запись.

Итак, еще раз, чтобы быть кристально чистым, когда пользователь из «Нью-Йорка» рецензирует (песню) «123», он создаст новую запись с идентификатором песни, названием штата и добавит рецензию.значения в 3 столбца stdjlike, stthinkclublike и stplait.Следующий пользователь, другой пользователь из Нью-Йорка, для песни «123» создает обзор, он просто обновляет запись, добавляя значения stdjlike, stthinkclublike и stplait к предыдущему отзыву.

Я искал вокругвсю неделю и найти множество хороших решений для похожих, но не одинаковых проблем ( Хорошо документированное решение здесь ).Я решил пойти с приращением, потому что я обновляю значения, которые не являются фиксированными числами, я пытался, но я просто не могу заставить его работать.

Я начал с того, что работает.Создание в контроллере состояния обзора сохраняет запись, когда это просто .new и .save.Так что я изменил его оттуда к этому ..

def create

@reviewstate = Reviewstate.find_or_initialize_by_songid_and_state(song.id, current_user.state)
@reviewstate.stdjlike.increment!(:stdjlike, reviewstate.stdjlike)
@reviewstate.stthinkclublike.increment!(:stthinkclublike, reviewstate.stthinkclublike)
@reviewstate.stplait.increment!(:stplait, reviewstate.stplait)
@reviewstate.save!
end

Перестает работать.Я пробовал разные варианты и методы, это когда я чувствую себя ближе всего.Пожалуйста, помогите мне, это было 4 дня:).

Спасибо заранее.

Ответы [ 2 ]

0 голосов
/ 08 апреля 2011

Это будет звучать довольно радикально, но я думаю, что в конечном итоге вам все будет проще. Я собираюсь рекомендовать довольно большой рефакторинг. Похоже, у вас есть несколько вещей, которые должны быть их собственными моделями:

  • Пользователь (или DJ)
  • Состояние
  • Песня
  • Обзор

Я бы структурировал приложение так, чтобы ваши обзоры принадлежали одному состоянию, одному пользователю и одной песне:

#user.rb
class User << ActiveRecord::Base
    has_many :reviews
end

#state.rb
class State << ActiveRecord::Base
    has_many :reviews
end

#song.rb
class Song << ActiveRecord::Base
    has_many :reviews
end

#review.rb
class Review << ActiveRecord::Base
    belongs_to :user
    belongs_to :state
    belongs_to :song
end

Затем, когда вы хотите собрать какую-либо форму статистики для отображения, вы извлекаете ее из записей обзора. Это позволит вам получать статистику по штатам, диджеям или песням.

Это также более RESTful-реализация, в которой больше объектов в вашей системе представлены как ресурсы, которые можно (C) восстанавливать, (R) читать, (U) добавлять и (D) создавать. В целом, выполнение RESTful делает вашу жизнь намного легче, работая на рельсах.

0 голосов
/ 08 апреля 2011

Если find не возвращает запись и инициализируется новая, stdjlike будет nil (если вы не установите другое значение по умолчанию в своей миграции). Таким образом, приращение будет пытаться увеличить на ноль. Nil не является fixnum, хотя и не будет работать. Я полагаю, что это ошибка, которую вы получаете.

Кроме того, вы сохраняете свой объект в @reviewstate, а затем ссылаетесь на него по адресу reviewstate.stdjlike. У вас есть переменная экземпляра @reviewstate, и вы затем обращаетесь к локальной переменной reviewstate. Это два разных объекта.

Вы должны обращаться с вещами по-другому. Проверьте, существует ли ваша запись. Если да, просто возьми это. Если нет, создайте его. Использовать Reviewstate.exists?.

Кроме того, имейте в виду, что Ruby использует подчеркивание в качестве соглашения для имен. Это сделало бы что-то вроде std_jlike или что-то в этом роде. Но вы всегда можете использовать то, что вам удобнее.

...