0

我有一个 Like 模型,它连接用户喜欢的项目。除了标准liked状态,项目可以是spinned& pinned,都是布尔字段。

喜欢模型

 _________________________________________________
| item_id | user_id |  liked  |  spinned | pinned |
|---------|---------|---------|----------|--------|
|    1    |    1    |  true   |   true   | false  |
|    2    |    1    |  false  |   true   | true   |
|    3    |    2    |  true   |   false  | false  |
 -------------------------------------------------

一个项目的不同状态都通过同一个AJAX调用更新,action在 my likes controller. 当同类尚不存在时,它会在所需状态为真的情况下创建同类。

喜欢控制器

def index
  # get the item id
  action = params[:act]
  mid = params[:mid]

  # gets the desired like item to see if it already exists
  like = Like.where(:item_id => mid, :user_id => current_user.id).first

  case action

    # like the item
    when "like"
      # if the item doesn't exist
      if like.blank?
        # create the like
        Like.create(:user_id => current_user.id, :item_id => mid, :liked => true)
      else
        # else toggle the liked status
        like.toggle! :liked
      end

    # pin the item
    when "pin"
      if like.blank?
        # create the like
        Like.create(:user_id => current_user.id, :item_id => mid, :pinned => true)
      else
        # else toggle the pinned status
        like.toggle! :pinned
      end

    # spin the item
    when "spin"
      if like.blank?
        # create the like
        Like.create(:user_id => current_user.id, :item_id => mid, :spinned => true)
      else
        # else toggle the spinned status
        like.toggle! :spinned
      end
  end
end

如您所见,代码case变得非常重复,我想知道是否可以action更有效地使用我的 ('like', 'pin', 'spin') 变量。

我可以action通过从我的view.

然后我可以使用它来只有一个代码块而不是 3 个类似的代码块吗?

IE

action = "liked" # this would change depending on the desired action

# if the item doesn't exist
if like.blank?
  # original
  Like.create(:user_id => current_user.id, :item_id => mid, :liked => true)
  # doesn't work, how would I do this appropriately?
  Like.create("user_id = ?, item_id = ?, ? = true", current_user.id, mid, action)
else
  # this works!, what about SQL injection? How can I prevent this?
  like.toggle!("#{action}")
end
4

2 回答 2

1

如果事件的原子性不是主要问题,您可以使用 select 或 new 然后保存。

like = Like.where(:item_id => mid, :user_id => current_user.id).first
like ||= Like.new(:item_id => mid, :user_id => current_user.id, :pinned => false, :spinned => false, :liked => false)
when "like"
like.liked = !like.liked
when "spin"
like.spinned = !like.spinned
when "pin"
like.pinned = !like.pinned
end
like.save!
于 2013-10-05T12:51:36.700 回答
0

事实证明,在使用 and 时,我可以简单地使用我的变量而不是action列选择器。:columncreate()toggle()

结果是:

if like.blank?
  # create the like
  Like.create(:user_id => current_user, :item_id => mid, action => true)
else
  # else toggle the desired status
  like.toggle!(action)
end  
于 2013-10-05T09:39:31.690 回答