我有三个模型User
,Anime
和Animelist
。
user
可以向anime
添加animelist
。这项工作正常,但我不希望user
能够在列表中添加相同的anime
无数次。
如何设置它,以便在用户将动画添加到列表后,会弹出一个编辑弹出窗体/按钮以及它们放入的信息。
我在动漫/节目页面中有一个弹出窗口,用于显示用户必须填写的表单,以便为其列表添加动画。希望我能清楚自己。
Animelist _form
<%= simple_form_for [@anime, @animelist] do |f| %>
<%= f.input :status %>
<%= f.input :rating %>
<%= f.input :rewatched %>
<% end %>
动漫/节目页面弹出代码
<p><a data-open="exampleModal1">Add to Animelist</a></p>
<div class="reveal form" id="exampleModal1" data-reveal>
<%= render partial: 'animelists/form' %>
<button class="close-button" data-close aria-label="Close modal" type="button">
<span aria-hidden="true">×</span>
</button>
</div>
动漫列表控制器
def new
@anime = Anime.friendly.find(params[:anime_id])
@animelist = Animelist.new
end
def create
@anime = Anime.friendly.find(params[:anime_id])
@animelist = Animelist.new(animelist_params)
@animelist.user_id = current_user.id
@animelist.anime_id = @anime.id
if @animelist.save
redirect_to :back
else
render :new
end
end
动漫控制器
def show
@anime = Anime.friendly.find(params[:id])
@animelist = Animelist.new
end
答案 0 :(得分:1)
您执行此操作的方法是在AnimeList
模型上使用validation,以确保每个anime_id
在使用user_id
确定范围时是唯一的:
#app/models/anime_list.rb
class AnimeList < ActiveRecord::Base
belongs_to :user
belongs_to :anime
validates :anime, uniqueness: { scope: :user_id, message: "%{attribute} already added" }
end
如果你使用相同的AnimeList
&amp; {},那么这会使每个新@anime.id
失败。 @user.id
,您可以在表单上输出错误。
<强>结构强>
您的整体结构存在一些问题,如果您想要正确显示错误,应该解决这个问题:
#config/initializers/friendly_id.rb
...
config.use :finders #-> uncomment so you don't need to call Model.friendly.find any more
#config/routes.rb
resources :animes do
resources :anime_lists, only: [:create, :destroy], path_names: { create: "add", destroy: "remove" } #-> url.com/animes/:anime_id/add
end
#app/controllers/animes_controller.rb
class AnimesController < ApplicationController
def show
@anime_list = current_user.anime_lists.new
end
end
#app/controllers/anime_lists_controller.rb
class AnimeListsController < ApplicationController
def create
@anime = Anime.find params[:anime_id]
@animelist = current_user.anime_lists.new animelist_params
respond_to do |format|
format.js
end
end
def destroy
@anime = Anime.find params[:anime_id]
@animelist = current_user.anime_lists.find(params[:id]).destroy
end
private
def animelist_params
params.require(:anime_list).permit(:status, :rating, :rewatched).merge(anime_id: @anime.id)
end
end
这将清理您可以使用的控制器:
#app/views/anime_lists/create.js.erb
$("#anime_list").html("<%=j render partial: \"anime_list/form\", locals: { anime_list: @anime_list } %>");
#app/views/anime_lists/_form.html.erb
<%= simple_form_for anime_list, url: anime_anime_list_path(@anime), remote: true do |f| %>
<%= f.input :status %>
<%= f.input :rating %>
<%= f.input :rewatched %>
<%= f.submit %>
<% end %>
<强>更新强>
您的错误提到animelist
没有User
方法:
这意味着每当您的请求到达控制器时,它就会尝试触发@user.animelist
;由于animelist
方法不存在,它正在吐出错误。
永远记住JS / Ajax请求只是pseudo
个请求。每次使用HTTP
时,都有向服务器发送请求。然后该请求被处理。你永远不会对错误感到茫然 - 他们总是在服务器日志的某个地方。
我猜测问题与您anime_list
协会的CamelCase
(或缺乏)有关:
#app/models/user.rb
class User < ActiveRecord::Base
has_many :animelists #-> model name "animelist.rb"
has_many :animes, through: :anime_lists
end
#app/user/animelist.rb
class Animelist < ActiveRecord::Base
belongs_to :user
belongs_to :anime
end
在这方面,我在调用current_user.animelist
时也犯了一个小错误 - 它应该是current_user.anime_lists
(复数)。这可能会解决您的问题。