如何在不同的页面中提交表单,然后在提交后显示编辑表单

时间:2016-02-09 00:53:40

标签: ruby-on-rails

我有三个模型UserAnimeAnimelist

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">&times;</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

1 个答案:

答案 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方法:

enter image description here

这意味着每当您的请求到达控制器时,它就会尝试触发@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(复数)。这可能会解决您的问题。