如何使用单个按钮将 object 标记和取消标记为 Rails 中的 'favorite'?
How to mark and unmark an object as a 'favorite' in Rails with a single button?
我实现了一项功能,用户可以将笑话标记为收藏夹。因为我已经将 acts_as_votable 用于 upvoting/downvoting,并且希望收藏不同于用户的赞成票,所以我自己构建了它。
现在,用户通过单击 'favorite' link 或 'unfavorite' link 创建收藏夹。这并不理想,因为用户可以通过这种方式创建重复的收藏夹。
我更愿意将其更改为一个开关,我首先检查用户是否已将笑话标记为收藏,然后根据该状态显示适当的操作。我不确定如何去做。谁能指出我正确的方向?
我的笑话控制器:
# Add and remove favorite jokes
# for current_user
def favorite
@joke = Joke.find(params[:id])
type = params[:type]
if type == "favorite"
current_user.favorites << @joke
redirect_to :back, notice: 'Added to favorites'
elsif type == "unfavorite"
current_user.favorites.delete(@joke)
redirect_to :back, notice: 'Removed from favorites'
else
# Type missing, nothing happens
redirect_to :back, notice: 'Nothing happened.'
end
end
我的模特:
(笑话)
has_many :favorite_jokes
has_many :favorited_by, through: :favorite_jokes, source: :user
(Favorite_Joke)
belongs_to :joke
belongs_to :user
(用户)
has_many :favorite_jokes
has_many :favorites, through: :favorite_jokes, source: :joke
我的看法:
<div class="col-sm-4 col-xs-12 text-center">
<button type="button" class="btn btn-danger btn-block">
<i class="fa fa-heart"></i>
<span class="badge">favorite</span>
</button>
</div>
<% if current_user %>
<%= link_to "favorite", favorite_joke_path(@joke, type: "favorite"), method: :put %>
<%= link_to "unfavorite", favorite_joke_path(@joke, type: "unfavorite"), method: :put %>
<% end %>
最后,我的路线:
resources :jokes do
member do
put "like" => "jokes#upvote"
put "unlike" => "jokes#downvote"
end
put :favorite, on: :member
end
如果 current_user 在 favorite_jokes table 那个特别的笑话。
在 jokes_controller#show 动作中:
@favorited = FavoriteJoke.find_by(user: current_user, joke: @joke).present?
然后在视图中,类似于:
<% if @favorited %>
<%= link_to "unfavorite", unfavorite_joke_path(@joke), method: :put %>
<% else %>
<%= link_to "favorite", favorite_joke_path(@joke), method: :put %>
<% end %>
然后在您的 routes.rb
文件中,为收藏和取消收藏创建一条路线,而不是在一次操作中执行该逻辑。
我实现了一项功能,用户可以将笑话标记为收藏夹。因为我已经将 acts_as_votable 用于 upvoting/downvoting,并且希望收藏不同于用户的赞成票,所以我自己构建了它。
现在,用户通过单击 'favorite' link 或 'unfavorite' link 创建收藏夹。这并不理想,因为用户可以通过这种方式创建重复的收藏夹。
我更愿意将其更改为一个开关,我首先检查用户是否已将笑话标记为收藏,然后根据该状态显示适当的操作。我不确定如何去做。谁能指出我正确的方向?
我的笑话控制器:
# Add and remove favorite jokes
# for current_user
def favorite
@joke = Joke.find(params[:id])
type = params[:type]
if type == "favorite"
current_user.favorites << @joke
redirect_to :back, notice: 'Added to favorites'
elsif type == "unfavorite"
current_user.favorites.delete(@joke)
redirect_to :back, notice: 'Removed from favorites'
else
# Type missing, nothing happens
redirect_to :back, notice: 'Nothing happened.'
end
end
我的模特: (笑话)
has_many :favorite_jokes
has_many :favorited_by, through: :favorite_jokes, source: :user
(Favorite_Joke)
belongs_to :joke
belongs_to :user
(用户)
has_many :favorite_jokes
has_many :favorites, through: :favorite_jokes, source: :joke
我的看法:
<div class="col-sm-4 col-xs-12 text-center">
<button type="button" class="btn btn-danger btn-block">
<i class="fa fa-heart"></i>
<span class="badge">favorite</span>
</button>
</div>
<% if current_user %>
<%= link_to "favorite", favorite_joke_path(@joke, type: "favorite"), method: :put %>
<%= link_to "unfavorite", favorite_joke_path(@joke, type: "unfavorite"), method: :put %>
<% end %>
最后,我的路线:
resources :jokes do
member do
put "like" => "jokes#upvote"
put "unlike" => "jokes#downvote"
end
put :favorite, on: :member
end
如果 current_user 在 favorite_jokes table 那个特别的笑话。
在 jokes_controller#show 动作中:
@favorited = FavoriteJoke.find_by(user: current_user, joke: @joke).present?
然后在视图中,类似于:
<% if @favorited %>
<%= link_to "unfavorite", unfavorite_joke_path(@joke), method: :put %>
<% else %>
<%= link_to "favorite", favorite_joke_path(@joke), method: :put %>
<% end %>
然后在您的 routes.rb
文件中,为收藏和取消收藏创建一条路线,而不是在一次操作中执行该逻辑。