jeudi 22 décembre 2016

Ruby on Rails Nested Attribute form broken, Database Rollback, error is not clear

I am still very new to Ruby on Rails so forgive me if the answer is obvious.

I am building an app with 3 models (User, Bundle, Entry) that have the following relations and for some reason, when I try to create a new Bundle with an entry while logged in as a user, I get some error (but I don't even see what the error is).

If I create a new bundle without the entry, it works as expected. And if I try to make a bundle from the rails console, it also works fine.

All I can discern is that whenever I try to create a new bundle and a new entry from the browser, I get a flash on the top of the screen (from flash[:danger] inside bundles#create) and this message in the console:

Started POST "/bundles" for ::1 at 2016-12-22 18:07:28 -0500
Processing by BundlesController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"ATsxcPqsH9whw3Jp/GgkNFgGR7ep2142ZRH27nLWpe/QSkvxSvNQOmerRVGa5ZlYaWJ99/NqlTVusqmlisBviA==", "bundle"=>{"name"=>"first", "entries_attributes"=>{"0"=>{"title"=>"bundle name", "url"=>"www.facebook.com", "_destroy"=>"0"}}}, "commit"=>"Add"}
  User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
   (0.1ms)  BEGIN
   (0.1ms)  ROLLBACK
  Rendered users/_user.html.erb (0.9ms)

Here are my models:

bundle.rb .

class Bundle < ApplicationRecord
  belongs_to :user
  has_many :entries, dependent: :destroy, inverse_of: :bundle
  accepts_nested_attributes_for :entries, reject_if: ->(attrs) { attrs['title'].blank? || attrs['url'].blank? }, allow_destroy: true

user.rb

class User < ApplicationRecord
  has_many :bundles, dependent: :destroy
  has_many :entries, through: :bundles

entry.rb

class Entry < ApplicationRecord
  belongs_to :bundle
  has_many :users, through: :bundle

Inside users#show, my view looks like this:

user show view: a list of user's bundles and a form to submit a new bundle

Here are my controller actions:

bundles_controller.rb

    def create
        @bundle = current_user.bundles.build(bundle_params)
        if @bundle.save
          flash[:success] = "Bundle Created!"
          redirect_back_or current_user
        else
          flash[:danger] = "Something went wrong"
          render current_user

        end
      end
private
    def bundle_params
        params.require(:bundle).permit(:name, entries_attributes: [:id, :title, :url, :_destroy])
    end

users_controller.rb

  def show
    @user = User.find(params[:id])
    @bundles = @user.bundles
    @bundle = current_user.bundles.new if logged_in?
    @bundle.entries.build
  end

entries_controller.rb

      def create
        @new_entry = Entry.new(entry_params)
        if @new_entry.save
          redirect_back_or root_path
        else
          render 'index'
        end


        end
private
      def entry_params
        params.require(:entry).permit(:title, :url)
      end

And here is the code for the form itself: _bundle_form.html.erb

   <%= form_for(@bundle) do |f| %>
        <%= render 'shared/error_messages', object: f.object %>
        <div class="field" >
          <%= f.text_area :name, placeholder: "Bundle name" %>
        </div>

        <div>
          <p><strong>Entries:</strong></p>
          <%= f.fields_for :entries do |entry| %>

                <%= entry.label :title %>
                <%= entry.text_area :title, placeholder: "title" %>
                <%= entry.text_area :url, placeholder: "URL" %>

          <% end %>
        </div>

        <%= f.submit "Add", class: "btn btn-primary" %>
    <% end %>

Thanks for any help anyone here might be able to offer.

Aucun commentaire:

Enregistrer un commentaire