1

I had just been having problems with creating new records as posted here Can't create new record via form in Rails 5 app, so not sure if this could be related.

The issue is that when I edit an existing record, the changes are captured fine, but it creates a duplicate and amends the URL with what looks like a hash: https://www.gourmetcoffee.london/coffeeshops/caravan-exmouth-market-2f9f6d3c-7ca3-4542-ac40-207104f835fa. I'm using friendly_ids gem to dynamically take the :name field and use that as the unique url.

I have other tables in the db which I can edit ok.

I saw a related question and his solution was to add the :id to the permited_params, I've ensured that :slug and :id are permitted, but this is not solved it so far.

my controller

class CoffeeshopsController < ApplicationController
http_basic_authenticate_with name: "****", password: "****", except: [:index, :show, :favorite, :bookmarked]

def index

  if params[:tag]
    @coffeeshops = Coffeeshop.tagged_with(params[:tag])
  else
    @coffeeshops = Coffeeshop.all
  end
    @coffeeshops = @coffeeshops.order("created_at ASC").page params[:page]
end

  def show

    @coffeeshop = Coffeeshop.find(params[:id])
    @last3_coffeeshops = Coffeeshop.last(3)
    @commentable = @coffeeshop
    @comments = @commentable.comments
    @comment = Comment.new
    @locale_cafe = Coffeeshop.where(locale: @coffeeshop.locale)
    @fave_count = @coffeeshop.favorited_by
    @user = User.all
    @currentuser = current_user
  end

  def new
  end

  def edit
    @coffeeshop = Coffeeshop.friendly.find(params[:id])
  end

  def create
    @coffeeshop = Coffeeshop.new(coffeeshop_params)

      if @coffeeshop.save
        redirect_to @coffeeshop
      else
        render 'new'
      end
  end

  def update
    @coffeeshop = Coffeeshop.friendly.find(params[:id])

    if @coffeeshop.update(coffeeshop_params)
      redirect_to @coffeeshop
    else
      render 'edit'
    end
  end

  def destroy
    @coffeeshop = Coffeeshop.find(params[:id])
    @coffeeshop.destroy

    redirect_to coffeeshops_path
  end


  def favorite
    @coffeeshop = Coffeeshop.find(params[:id])
    type = params[:type]
    if type == "favorite"
      current_user.favorites << @coffeeshop
      redirect_to :back, notice: "You favorited #{@coffeeshop.name}"

    elsif type == "unfavorite"
      current_user.favorites.delete(@coffeeshop)
      redirect_to :back, notice: "Unfavorited #{@coffeeshop.name}"

    else
      # Type missing, nothing happens
      redirect_to :back, notice: "Nothing happened."
    end
  end

  def bookmarked
    @coffeeshop = Coffeeshop.find(params[:id])
    type = params[:type]
    if type == "bookmarked"
      current_user.bookmarks << @coffeeshop
      redirect_to :back, notice: "You bookmarked #{@coffeeshop.name}"

    elsif type == "unbookmark"
      current_user.bookmarks.delete(@coffeeshop)
      redirect_to :back, notice: "You removed #{@coffeeshop.name} bookmark"

    else
      # Type missing, nothing happens
      redirect_to :back, notice: "Nothing happened."
    end
  end



  private
    def coffeeshop_params
      params.require(:coffeeshop).permit(:name, :desc, :area, :url, :email, :address, :postcode, :locale, :phone, :image_path, :image_thumb_path, :snippet, :beans, :long_black, :tag_list, :slug, :id)
    end
end

model

class Coffeeshop < ApplicationRecord
  paginates_per 5
  include PgSearch
  pg_search_scope :search_by_full_name, against: [:name]
  require 'acts-as-taggable-on'
  acts_as_taggable
  #acts_as_taggable_on :tag_list


  has_many :comments, as: :commentable
  belongs_to :roaster
  belongs_to :user
  has_many :favorite_coffeeshops# just the 'relationships'
  has_many :favorited_by, through: :favorite_coffeeshops, source: :user
  has_many :bookmarked_coffeeshops# just the 'relationships'
  has_many :bookmarked_by, through: :bookmarked_coffeeshops, source: :user

  validates :name, :snippet, :area, :image_thumb_path, :image_path, :presence => true


  extend FriendlyId
    friendly_id :name, use: [:slugged, :finders]




    private
    def should_generate_new_friendly_id?
      slug.nil? || name_changed?
    end

end

routes

Simons-MBP:gourmet_coffee Simon$ rails routes
                          Prefix Verb     URI Pattern                                             Controller#Action
                        roasters GET      /roasters(.:format)                                     roasters#index
                                 POST     /roasters(.:format)                                     roasters#create
                     new_roaster GET      /roasters/new(.:format)                                 roasters#new
                    edit_roaster GET      /roasters/:id/edit(.:format)                            roasters#edit
                         roaster GET      /roasters/:id(.:format)                                 roasters#show
                                 PATCH    /roasters/:id(.:format)                                 roasters#update
                                 PUT      /roasters/:id(.:format)                                 roasters#update
                                 DELETE   /roasters/:id(.:format)                                 roasters#destroy
                      home_index GET      /home/index(.:format)                                   home#index
                            root GET      /                                                       home#index
                new_user_session GET      /auth/sign_in(.:format)                                 users/sessions#new
                    user_session POST     /auth/sign_in(.:format)                                 users/sessions#create
            destroy_user_session DELETE   /auth/sign_out(.:format)                                users/sessions#destroy
user_facebook_omniauth_authorize GET|POST /auth/auth/facebook(.:format)                           users/omniauth_callbacks#passthru
 user_facebook_omniauth_callback GET|POST /auth/auth/facebook/callback(.:format)                  users/omniauth_callbacks#facebook
               new_user_password GET      /auth/password/new(.:format)                            devise/passwords#new
              edit_user_password GET      /auth/password/edit(.:format)                           devise/passwords#edit
                   user_password PATCH    /auth/password(.:format)                                devise/passwords#update
                                 PUT      /auth/password(.:format)                                devise/passwords#update
                                 POST     /auth/password(.:format)                                devise/passwords#create
        cancel_user_registration GET      /auth/cancel(.:format)                                  users/registrations#cancel
           new_user_registration GET      /auth/sign_up(.:format)                                 users/registrations#new
          edit_user_registration GET      /auth/edit(.:format)                                    users/registrations#edit
               user_registration PATCH    /auth(.:format)                                         users/registrations#update
                                 PUT      /auth(.:format)                                         users/registrations#update
                                 DELETE   /auth(.:format)                                         users/registrations#destroy
                                 POST     /auth(.:format)                                         users/registrations#create
         destroy_fb_user_session DELETE   /sign_out(.:format)                                     devise/sessions#destroy
                     new_message GET      /contact-me(.:format)                                   messages#new
                  create_message POST     /contact-me(.:format)                                   messages#create
                           title GET      /article(.:format)                                      articles#show
                       longblack GET      /longblack(.:format)                                    longblack#index
                          prices GET      /prices(.:format)                                       prices#new
                                 POST     /prices(.:format)                                       prices#create
                           about GET      /about(.:format)                                        pages#about
                    cookiepolicy GET      /cookiepolicy(.:format)                                 pages#cookiepolicy
                             map GET      /map(.:format)                                          pages#map
                             tag GET      /articles/tags/:tag(.:format)                           articles#index
                 coffeeshops_tag GET      /coffeeshops/tags/:tag(.:format)                        coffeeshops#index
                    roasters_tag GET      /roasters/tags/:tag(.:format)                           roasters#index
                roaster_comments GET      /roasters/:roaster_id/comments(.:format)                comments#index
                                 POST     /roasters/:roaster_id/comments(.:format)                comments#create
             new_roaster_comment GET      /roasters/:roaster_id/comments/new(.:format)            comments#new
            edit_roaster_comment GET      /roasters/:roaster_id/comments/:id/edit(.:format)       comments#edit
                 roaster_comment GET      /roasters/:roaster_id/comments/:id(.:format)            comments#show
                                 PATCH    /roasters/:roaster_id/comments/:id(.:format)            comments#update
                                 PUT      /roasters/:roaster_id/comments/:id(.:format)            comments#update
                                 DELETE   /roasters/:roaster_id/comments/:id(.:format)            comments#destroy
                                 GET      /roasters(.:format)                                     roasters#index
                                 POST     /roasters(.:format)                                     roasters#create
                                 GET      /roasters/new(.:format)                                 roasters#new
                                 GET      /roasters/:id/edit(.:format)                            roasters#edit
                                 GET      /roasters/:id(.:format)                                 roasters#show
                                 PATCH    /roasters/:id(.:format)                                 roasters#update
                                 PUT      /roasters/:id(.:format)                                 roasters#update
                                 DELETE   /roasters/:id(.:format)                                 roasters#destroy
                article_comments GET      /articles/:article_id/comments(.:format)                comments#index
                                 POST     /articles/:article_id/comments(.:format)                comments#create
             new_article_comment GET      /articles/:article_id/comments/new(.:format)            comments#new
            edit_article_comment GET      /articles/:article_id/comments/:id/edit(.:format)       comments#edit
                 article_comment GET      /articles/:article_id/comments/:id(.:format)            comments#show
                                 PATCH    /articles/:article_id/comments/:id(.:format)            comments#update
                                 PUT      /articles/:article_id/comments/:id(.:format)            comments#update
                                 DELETE   /articles/:article_id/comments/:id(.:format)            comments#destroy
                        articles GET      /articles(.:format)                                     articles#index
                                 POST     /articles(.:format)                                     articles#create
                     new_article GET      /articles/new(.:format)                                 articles#new
                    edit_article GET      /articles/:id/edit(.:format)                            articles#edit
                         article GET      /articles/:id(.:format)                                 articles#show
                                 PATCH    /articles/:id(.:format)                                 articles#update
                                 PUT      /articles/:id(.:format)                                 articles#update
                                 DELETE   /articles/:id(.:format)                                 articles#destroy
             coffeeshop_comments GET      /coffeeshops/:coffeeshop_id/comments(.:format)          comments#index
                                 POST     /coffeeshops/:coffeeshop_id/comments(.:format)          comments#create
          new_coffeeshop_comment GET      /coffeeshops/:coffeeshop_id/comments/new(.:format)      comments#new
         edit_coffeeshop_comment GET      /coffeeshops/:coffeeshop_id/comments/:id/edit(.:format) comments#edit
              coffeeshop_comment GET      /coffeeshops/:coffeeshop_id/comments/:id(.:format)      comments#show
                                 PATCH    /coffeeshops/:coffeeshop_id/comments/:id(.:format)      comments#update
                                 PUT      /coffeeshops/:coffeeshop_id/comments/:id(.:format)      comments#update
                                 DELETE   /coffeeshops/:coffeeshop_id/comments/:id(.:format)      comments#destroy
                     coffeeshops GET      /coffeeshops(.:format)                                  coffeeshops#index
                                 POST     /coffeeshops(.:format)                                  coffeeshops#create
                  new_coffeeshop GET      /coffeeshops/new(.:format)                              coffeeshops#new
                 edit_coffeeshop GET      /coffeeshops/:id/edit(.:format)                         coffeeshops#edit
                      coffeeshop GET      /coffeeshops/:id(.:format)                              coffeeshops#show
                                 PATCH    /coffeeshops/:id(.:format)                              coffeeshops#update
                                 PUT      /coffeeshops/:id(.:format)                              coffeeshops#update
                                 DELETE   /coffeeshops/:id(.:format)                              coffeeshops#destroy
             favorite_coffeeshop PUT      /coffeeshops/:id/favorite(.:format)                     coffeeshops#favorite
                                 GET      /coffeeshops(.:format)                                  coffeeshops#index
                                 POST     /coffeeshops(.:format)                                  coffeeshops#create
                                 GET      /coffeeshops/new(.:format)                              coffeeshops#new
                                 GET      /coffeeshops/:id/edit(.:format)                         coffeeshops#edit
                                 GET      /coffeeshops/:id(.:format)                              coffeeshops#show
                                 PATCH    /coffeeshops/:id(.:format)                              coffeeshops#update
                                 PUT      /coffeeshops/:id(.:format)                              coffeeshops#update
                                 DELETE   /coffeeshops/:id(.:format)                              coffeeshops#destroy
           bookmarked_coffeeshop PUT      /coffeeshops/:id/bookmarked(.:format)                   coffeeshops#bookmarked
                                 GET      /coffeeshops(.:format)                                  coffeeshops#index
                                 POST     /coffeeshops(.:format)                                  coffeeshops#create
                                 GET      /coffeeshops/new(.:format)                              coffeeshops#new
                                 GET      /coffeeshops/:id/edit(.:format)                         coffeeshops#edit
                                 GET      /coffeeshops/:id(.:format)                              coffeeshops#show
                                 PATCH    /coffeeshops/:id(.:format)                              coffeeshops#update
                                 PUT      /coffeeshops/:id(.:format)                              coffeeshops#update
                                 DELETE   /coffeeshops/:id(.:format)                              coffeeshops#destroy
                                 GET      /coffeeshops(.:format)                                  coffeeshops#index
                                 GET      /                                                       coffeeshops#index
                 coffeeshops_new GET      /coffeeshops/new(.:format)                              coffeeshops#new
                 coffeeshopseast GET      /coffeeshopseast(.:format)                              coffeeshopseast#index
              coffeeshopscentral GET      /coffeeshopscentral(.:format)                           coffeeshopscentral#index
                         profile GET      /profile(.:format)                                      profile#show
                            page GET      /pages/*id                                              high_voltage/pages#show

form

<%= form_for :coffeeshop, url: coffeeshops_path do |f| %>
<form>
  <div class="form-group">
    <p>
      <%= f.label :Name %><br>
      <%= f.text_field :name, class: "form-control" %>
    </p>
  </div>
<div class="form-group">
  <p>
    <%= f.label :Snippet %><br>
    <%= f.text_area :snippet, class: "form-control", rows: "2" %>
  </p>
  </div>
<div class="form-group">
  <p>
    <%= f.label :Desciption %><br>
    <%= f.text_area :desc, class: "form-control", rows: "8" %>
  </p>
  </div>
<div class="form-group">
  <p>
    <%= f.label :Area %><br>
    <%= f.text_area :area, class: "form-control" %>
  </p>
  </div>

<div class="form-group">
  <p>
    <%= f.label :Locale %><br>
    <%= f.text_area :locale, class: "form-control" %>
  </p>
</div>
<div class="form-group">
  <p>
    <%= f.label :URL %><br>
    <%= f.text_area :url, class: "form-control" %>
  </p>
<div class="form-group">
  <p>
    <%= f.label :email %><br>
    <%= f.text_area :email, class: "form-control" %>
  </p>
  </div>
<div class="form-group">
  <p>
    <%= f.label :Address %><br>
    <%= f.text_area :address, class: "form-control" %>
  </p>
  </div>
<div class="form-group">
  <p>
    <%= f.label :Postcode %><br>
    <%= f.text_area :postcode, class: "form-control" %>
  </p>
  </div>
<div class="form-group">
  <p>
    <%= f.label :Phone %><br>
    <%= f.text_area :phone, class: "form-control" %>
  </p>
  </div>
<div class="form-group">
  <p>
    <%= f.label :Thumbnail %><br>
    <%= f.text_area :image_thumb_path, class: "form-control" %>
  </p>
  </div>
<div class="form-group">
  <p>
    <%= f.label :Image %><br>
    <%= f.text_area :image_path, class: "form-control" %>
  </p>
  </div>
<div class="form-group">
  <p>
    <%= f.label :Beans %><br>
    <%= f.text_area :beans, class: "form-control" %>
  </p>
  </div>
<div class="form-group">
  <p>
    <%= f.label :Price_of_long_black %><br>
    <%= f.text_area :long_black, class: "form-control" %>
  </p>
  </div>



  <p class="uk-text-right">
              <%= link_to 'Cancel', coffeeshops_path(@coffeeshops), class: "btn btn-warning" %>

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

Solution

For clarity, I'll add the set-up:

Using the same form via a partial for new and update:

<%= form_for @coffeeshop do |f| %>

Found I was trying to use the friendly URL to update causing the duplication on id. Using the below solved it:

  def update
    @coffeeshop = Coffeeshop.find(params[:id]) #<was Coffeeshop.friendly.find(params[:id])

    if @coffeeshop.update(coffeeshop_params)
      redirect_to @coffeeshop
    else
      render 'edit'
    end
  end
Simon Cooper
  • 1,574
  • 4
  • 24
  • 53

3 Answers3

1

try below code:

for update

<%= form_for :coffeeshop, url: coffeeshop_path(@coffeeshop.id), method: :put do |f| %>

for create

<%= form_for :coffeeshop, url: coffeeshops_path do |f| %>|

Check your routes:

     coffeeshops GET      /coffeeshops(.:format)                                  coffeeshops#index
                 POST     /coffeeshops(.:format)                                  coffeeshops#create
  new_coffeeshop GET      /coffeeshops/new(.:format)                              coffeeshops#new
 edit_coffeeshop GET      /coffeeshops/:id/edit(.:format)                         coffeeshops#edit
      coffeeshop GET      /coffeeshops/:id(.:format)                              coffeeshops#show
                 PATCH    /coffeeshops/:id(.:format)                              coffeeshops#update
                 PUT      /coffeeshops/:id(.:format)                              coffeeshops#update

If you use same form_for for create and update then use below code:

<% url = (params[:action]=="create" ? coffeeshops_path : coffeeshop_path(@coffeeshop.id.id)) %>

<% method = (params[:action]=="create" ? "post" : "put")%>

<%= form_for :coffeeshop, url: url, method: method do |f| %>|
  ...
<% end %>
puneet18
  • 4,341
  • 2
  • 21
  • 27
  • if its not work then we can add another variable like `<% method = (params[:action]=="create" ? "post" : "put")%>` and pass in `form_for` – puneet18 Jun 13 '17 at 09:21
  • But then my friend how you pass `:id` to *update*? It only possible with `@coffeeshop`(which will be a resource here) instead of `:coffeeshop` – Pavan Jun 13 '17 at 09:24
  • url should be like `<% url = (params[:action]=="create" ? coffeeshops_path : coffeeshop_path(@coffeeshop.id.id)) %>` – puneet18 Jun 13 '17 at 09:25
  • Yes I'm actually finding it is updating without the hash being added to the URL, but it is in fact still creating a duplicate record so clearly isn't editing the :`id` – Simon Cooper Jun 13 '17 at 09:29
  • Just solved it. I had `@coffeeshop = Coffeeshop.friendly.find(params[:id])` instead of `@coffeeshop = Coffeeshop.find(params[:id])` – Simon Cooper Jun 13 '17 at 09:31
  • can you paste the code of query show in your terminal – puneet18 Jun 13 '17 at 09:31
  • 1
    '@coffeeshop.id.id' ? – Md. Farhan Memon Jun 13 '17 at 09:33
1

You need to initialize @coffeeshop in your new action and then you can use same form

def new
  @coffeeshop = CoffeeShop.new
end

In your view,

<%= form_for @coffeeshop do |f| %>

Rails has the understanding as to call which action based on the object passed..

Refer Resource-oriented style here

Md. Farhan Memon
  • 6,055
  • 2
  • 11
  • 36
0

You are using same form for create and update which is causing the problem. You need to add method: :put for update. Also the url should be coffeeshop_path(@cofeeshop)

<%= form_for :coffeeshop, url: coffeeshop_path(@cofeeshop), method: put do |f| %>
Pavan
  • 33,316
  • 7
  • 50
  • 76