Wesly February 2016

How to submit a form in a different page and then make an edit form display after being submitted

I have three models User, Anime and Animelist.

A user is able to add an anime to their animelist. This works just fine but i don't want a user to be able to add the same anime countless times to their list.

How can i set it up so after a user adds a anime to their list an edit pop-up form/button pops out with the info they put in.

I have a pop-up window in the animes/show page to reveal a form that a user has to fill to add a anime to their list. Hopefully I'm making my self clear.

Animelist _form

 <%= simple_form_for [@anime, @animelist] do |f| %>
   <%= f.input :status %>
   <%= f.input :rating %>
   <%= f.input :rewatched %>
 <% end %>

animes/show page pop-up code

 <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>

Animelist controller

 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

Anime controller

 def show
   @anime = Anime.friendly.find(params[:id])
   @animelist = Animelist.new
 end

Answers


Richard Peck February 2016

The way you'd do this is to use a validation on the AnimeList model to make sure each anime_id is unique when scoped with 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

This will make each new AnimeList fail if it you're using the same @anime.id & @user.id, an error which you can output on your form.


Structure

There are some issues with your overall structure, which should be addressed if you want to show the errors properly:

#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

This will clean up your controller, to which you'll be able to use:

Post Status

Asked in February 2016
Viewed 3,855 times
Voted 13
Answered 1 times

Search




Leave an answer