编辑现有记录会创建重复的Rails 5

时间:2017-06-13 08:51:15

标签: ruby-on-rails ruby activerecord rails-activerecord

我刚刚在Can't create new record via form in Rails 5 app发布新记录时遇到了问题,所以不确定这是否相关。

问题在于,当我编辑现有记录时,可以很好地捕获更改,但它会创建一个副本,并使用看起来像哈希的内容修改URL:https://www.gourmetcoffee.london/coffeeshops/caravan-exmouth-market-2f9f6d3c-7ca3-4542-ac40-207104f835fa。我使用friendly_ids gem动态获取:name字段并将其用作唯一网址。

我在db中有其他表,我可以编辑好。

我看到了related question,他的解决方案是将:id添加到permited_pa​​rams,我确保允许:slug:id,但是这个到目前为止还没有解决。

我的控制器

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

模型

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

路由

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

解决方案

为清楚起见,我将添加设置:

使用相同的表格通过部分表示新的和更新:

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

发现我试图使用友好的URL进行更新,导致id上的重复。使用下面解决了它:

  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

3 个答案:

答案 0 :(得分:1)

尝试以下代码:

更新

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

for create

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

检查您的路线:

     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

如果您使用相同的form_for进行创建和更新,请使用以下代码:

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

答案 1 :(得分:1)

您正在使用相同的表单进行创建和更新,从而导致问题。您需要为更新添加method: :puturl也应为coffeeshop_path(@cofeeshop)

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

答案 2 :(得分:1)

您需要在@coffeeshop操作中初始化new,然后才能使用相同的表单

def new
  @coffeeshop = CoffeeShop.new
end

在您看来,

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

Rails理解根据传递的对象调用哪个action

参考面向资源的风格 here