Обновить значение с помощью first_or_create в рельсах

У меня есть таблица «Нравится» со столбцами «business_id», «user_id» и «нравится» (0,1) и функция «change_like_status».

Теперь при каждом вызове функции, если значение равно 1, установите для него значение 0 (или наоборот), а если запись не существует, создайте ее со значением 1.

Метод first_or_create работает нормально, но как я могу переключить значение столбца «понравилось» при использовании этого метода?

Вот моя функция:

def change_like_status
  if current_user.present?
    status = Like.where("business_id = ? AND user_id = ?",params['id'],current_user.id).first_or_create(:business_id => params['id'],:user_id => current_user.id,:liked => '1')
    abort status.inspect
  else
    return render :json => {:status => false,:msg=>"You need to sign in before performing this action."}
  end
end

person manoj    schedule 31.08.2015    source источник


Ответы (2)


В вашем контроллере внесите изменения

def change_like_status
  if current_user
    status = Like.create_or_change_status(params[:id], current_user.id)
  else
    return render json: { status: false, msg: "You need to sign in before performing this action." }
  end

конец

В файле вашей модели like.rb добавьте метод

def self.create_or_change_status(business_id, user_id)
   status = where(business_id: business_id, user_id: user_id).first
   if status.nil?
      status = create({business_id: business_id, user_id: user_id, liked: 1})
   else
      status.update_attributes(liked: !status.liked)
   end
   status
end
person Amit Badheka    schedule 31.08.2015
comment
вместо update_attributes вы можете использовать update_column, который не будет вызывать обратные вызовы и просто записывает в БД - person Tim Kretschmer; 31.08.2015
comment
@huanson, он меняется в зависимости от требований, хочу ли я, чтобы обратные вызовы работали или нет - person Amit Badheka; 31.08.2015

def change_like_status
  if current_user
    current_user.likes.find_by(business_id: params[:id]).switch_status!
  else
    return render json: { status: false, msg: "You need to sign in before performing this action." }
  end
end

class Like
  def switch_status!
    self.update_column :liked, !liked
  end
end

другой подход должен быть примерно таким

class Like
  def switch_status!
    self.update_column :liked, !liked
  end
end


class User
  def likes id
    likes_for_business id
  end

  def likes_for_business(id)
    likes.find_by(business_id: id) || likes.create(:business_id: id, liked: true)
  end
end

# controller
current_user.likes(params[:id]).switch_status!
person Tim Kretschmer    schedule 31.08.2015
comment
Выдает ошибку: неопределенный метод `find_by' для 1:Fixnum - person manoj; 31.08.2015
comment
какое отношение лайков? что возвращает current_user.likes? должна быть коллекция дополненной реальности, если она нравится has_many? - person Tim Kretschmer; 31.08.2015