Rails update action/ / edit form not updating /not updating correctly

542 views Asked by At

So, I have a rails app that has a seed of all drama names/genre, and I'm doing a CRUD of reviews for them. For some reason, my create/new form works fine, but when I update, it will replace that drama I made a review for before with the current one I just made... SOS!

Edit: I updated this so there are all my models as well as the drama seed! I want to be able to update my review form without it duplicating itself or taking over another dramas' review I made!

So for the first form i provided, I tested it out and it works for CREATING a new review, but doesn't for UPDATING. The second form worked for UPDATING, but I want to make it so its just one form, since form_for is there for that!

Here is my reviews controller :

    class ReviewsController < ApplicationController
before_action :find_by_review, only: [:show, :edit, :update, :destroy]
before_action :current_user, only: [:create, :update, :edit, :destroy]

    def new 
        @review = Review.new 
    end 

    def show 
    end 

    def create 
        @review = Review.new(review_params)
        @drama = Drama.find(session[:drama_id])
        if @review.save
            redirect_to drama_review_path(@drama, @review), info: "You've created a new review!"
        else 
            @errors = @review.errors.full_messages
            render :new 
        end 
    end 

    def edit 
        
    end 

    def update 
        @review.update(review_params)
        if @review
        redirect_to user_path(@user), info: "You've successfully updated your review!"
        else 
            @errors = @user.errors.full_messages
            render :edit
        end 
    end 

    def destroy 
        @review.destroy
        redirect_to user_path(@user), info: "You've successfully deleted your review!"
    end 

    private 

    def review_params 
        params.require(:review).permit(:title, :content, :rating, :user_id, :drama_id)
    end 
end

Here is my new/edit form :

    <% @errors && @errors.each do |m|%>
     <li><%= m %></li>
    <%end%>

    <%= form_for @review do |f| %>
    <%= f.label :title %>
    <%= f.text_field :title %><br>
    <%= f.label :rating %>
    <%= f.number_field :rating %><br>
    <%= f.label :content %>
    <%= f.text_area :content %><br>
    <%= f.hidden_field :drama_id, value: session[:drama_id]%>
    <%= f.hidden_field :user_id, value: current_user.id%>
    <%= f.submit%>
    <%end%>
    
    <%=button_to "Main Page", dramas_path, method: :get%>

Here is my drama model :

class Drama < ApplicationRecord
    has_many :reviews 
    has_many :users, :through => :reviews
    validates :name, presence: true, uniqueness: true
    validates :genre, presence: true 
    before_validation :make_title_case  
    accepts_nested_attributes_for :reviews
    

    def self.alphabetized
        all.order('name asc')
    end
    private

    def make_title_case
    self.name = self.name.titlecase
    end
end

Here is my review model :

class Review < ApplicationRecord
    belongs_to :user 
    belongs_to :drama 
    validates :rating, presence: true, length: { maximum: 10 }
    validates :content, presence: true 
    validates :title, presence: true 

    def self.rating_limit
        all.where('rating desc').limit(10)
    end 
end

Here is my user model :

class User < ApplicationRecord
    has_many :reviews 
    has_many :dramas, :through => :reviews
    validates :username, uniqueness: true, presence: true 
    validates :email, uniqueness: true, presence: true 
    has_secure_password 
end

Here is the drama seed :

dramas = [
    {name: "Goblin", genre: "Comedy, Romance, Fantasy, Melodrama, Supernatural"},
    {name: "Its Okay, thats Love", genre: "Friendship, Psychological, Comedy, Romance, Drama"},
    {name: "Its Okay to Not be Okay", genre: "Psychological, Comedy, Romance, Drama, Family"},
    {name: "Start-Up", genre: "Business, Comedy, Romance, Youth, Drama"},
    {name: "Secret", genre: "Romance, Drama, Melodrama"},
    {name: "Secret Garden", genre: "Comedy, Romance, Drama, Melodrama, Supernatural"},
    {name: "Flower of Evil", genre: "Thriller, Mystery, Psychological, Romance, Crime, Melodrama"},
    {name: "Strong Woman Do Bong Soon", genre: "Action, Thriller, Comedy, Romance, Drama, Supernatural"},
    {name: "W", genre: "Action, Suspense, Thriller, Comedy, Romance, Drama, Fantasy, Melodrama"},
    {name: "Pinocchio", genre: "Thriller, Mystery, Comedy, Romance, Melodrama"},
    {name: "Healer", genre: "Action, Thriller, Mystery, Comedy, Romance, Drama"},
    {name: "While You were Sleeping", genre: "Thriller, Mystery, Comedy, Romance, Drama, Fantasy"},
    {name: "The Smile has Left your Eye", genre: "Thriller, Mystery, Romance, Drama"},
    {name: "Kill me, Heal me", genre: "Psychological, Comedy, Romance, Drama"},
    {name: "I'm not a robot", genre: "Friendship, Comedy, Romance, Drama, Sci-Fi"},
    {name: "The Beauty inside", genre: "Comedy, Romance, Family, Melodrama, Supernatural"},
    {name: "Angel's last mission: Love", genre: "Comedy, Romance, Drama, Fantasy"},
    {name: "King: Eternal Monarch", genre:  "Mystery, Romance, Drama, Fantasy"},
    {name: "My Girlfriend is a Gumhiho", genre: "Comedy, Romance, Drama, Fantasy, Supernatural"},
    {name: "Tale of the Nine-Tailed", genre: "Action, Suspense, Thriller, Horror, Romance, Fantasy"},
    {name: "Weightlifting Fairy Kim Bok Joo", genre: "Friendship, Comedy, Romance, School, Youth, Sports"},
    {name: "Boys over Flowers", genre: "Friendship, Comedy, Romance, School, Youth, Drama"},
    {name: "What's Wrong with Secretary Kim", genre: "Friendship, Business, Comedy, Romance"},
    {name: "Cheese in the Trap", genre: "Friendship, Psychological, Romance, Life, Drama"},
    {name: "Dream High", genre: "Friendship, Music, Comedy, Romance, School, Drama"},
    {name: "Oh My Venus", genre: "Friendship, Comedy, Law, Romance, Life, Drama, Sports"}
 ]

dramas.each do |drama|
    Drama.create drama 
end

Here is the form that is able to correctly update reviews:

<%= form_for @review do |f| %>
<%= f.label :title %>
<%= f.text_field :title %><br>
<%= f.label :rating %>
<%= f.number_field :rating %><br>
<%= f.label :content %>
<%= f.text_area :content %><br>
<%= f.hidden_field :drama_id, value: @review.drama_id%>
<%= f.hidden_field :user_id, value: current_user.id%>
<%= f.submit%>
<%end%>

Here is my routes.rb :

Rails.application.routes.draw do



resources :dramas do
    resources :reviews, only: [:new, :show, :edit, :update]
  end

  resources :dramas 
  resources :users
  resources :reviews 

  get '/auth/facebook/callback', to: 'sessions#create_with_fb'
  get '/', to: 'sessions#home'
  get '/signup', to: 'users#new'
  post '/signup', to: 'users#create'
  get '/login', to: 'sessions#new'
  post '/login', to: 'sessions#create'
  post '/logout', to: 'sessions#destroy'
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end
1

There are 1 answers

8
Anuj On

You have two entries for resources :reviews in your routes. One nested within dramas, the other outside. Ideally you should keep only one (Nested routes)

  resources :dramas do
    resources :reviews, only: [:new, :show, :edit, :update]
  end

the drama id will be available in the drama_id param inside the ReviewController.

So some of the changes you will need in your ReviewsController are

  before_action :init_drama

  def new 
    @review = @drama.reviews.new
  end

  def create 
    @review = Review.new(review_params)
    if @review.save
      redirect_to drama_review_path(@review.drama, @review), info: "You've created a new review!"
    else 
      @errors = @review.errors.full_messages
      render :new
    end
  end

  private

  def init_drama
    @drama = Drama.find(params[:drama_id])
  end