修正不一致的路线名称(路轨)

时间:2019-04-10 19:42:01

标签: ruby-on-rails routes ruby-on-rails-5.2

路线

resources :favorites, only: [ :index, :create, :destroy ] , param: :listing_id 

耙道

favorites GET    /favorites(.:format)             favorites#index
favorites POST   /favorites(.:format)             favorites#create
favorite DELETE /favorites/:listing_id(.:format)  favorites#destroy

请注意收藏夹中的(s),为什么不是全部收藏夹或收藏夹?

我创建了一个收藏夹并销毁了一个收藏夹,所以我认为两者都应该是单数的。

我需要

favorite POST   /favorites/:listing_id(.:format)       favorites#create

我在自己的路线上尝试过:

resources :favorites, only: [ :index, :destroy
 ] , param: :listing_id 

post 'favorites/:listing_id' => 'favorite#create', as: :favorite 

但出现此错误:

  

ArgumentError:无效的路由名称,已在使用中:'favorite'您可能   使用:as选项定义了两个具有相同名称的路由,或者   您可能会使用覆盖资源已定义的路由   相同的命名。对于后者,您可以限制使用创建的路由   resources,如此处所述:   http://guides.rubyonrails.org/routing.html#restricting-the-routes-created

该如何修改?

由于多种原因,我该如何保持一致,因为我需要在视图中创建一致的路径并销毁一致的路径。

我的控制器

class FavoritesController < ApplicationController

  before_action :load_listing, only: [:create, :destroy]

  def index
    @favorites = current_user.favorites.map{|i| i.id} || []
    @listings = ListingsQuery::Search.call(:favorited_ids=>  current_user.favorites.map{|i| i.id} )

    respond_to do |format|
        format.html {}
        format.js {}
    end
  end

   def create
    if current_user.favorite!(@listing)
      format.js {}
    end
  end

  def destroy
    if current_user.unfavorite!(@listing)
      format.js {}
    end
  end

  private 

  def load_listing
    @listing_id = favorite_params[:listing_id]
    @listing = Listing.find(@listing_id)
  end

  def favorite_params
    params.permit(:listing_id)
  end

end

视图

<% if listing.is_favorited == true  %>

  <%= link_to favorite_path(:listing_id => listing.listing_id), method: :delete, remote: true do%>
      <i id='i-<%= listing.listing_id %>' class=" fa fa-heart"></i>
    <% end %>

  <% else %>

  <%= link_to favorite_path(:listing_id => listing.listing_id), method: :post, remote: true do %>
      <i id='i-<%= listing.listing_id %>' class="fa fa-heart-o"></i>
    <% end %>

<% end %>

create.js

(function(){
  $("#i-<%= @listing_id %>").removeClass('fa-heart-o');
  $("#i-<%= @listing_id %>").addClass('fa-heart');
  $("#i-<%= @listing_id %>").parent().attr("data-method",'delete');

})();

这是为什么...

resources :favorite do
  collection do
    post "for_lisiting/:listing_id", action: :create_for_listing
    delete "for_listing/:listing_id", action: :delete_for_listing
  end
end

对此优先。

 match 'favorite' => 'favorites#create', via: :post
 match  'favorite' => 'favorites#destroy', via: :delete

在我看来,但也许我错了。

/favorite/for_lisiting/:listing_id(.:format) 

相比,

不必要地长

/favorite/:listing_id(.:format) 

但是,我是新手,因此请重视您的推理。

1 个答案:

答案 0 :(得分:0)

使用rails resource帮助程序时,它将创建一些REST端点。您有可以收藏的列表,您正在混合两种资源。您的资源是列表,而收藏夹/不喜欢/收藏夹是对资源的操作。

尝试这样的事情:

resources :listings do
  member do
    post :favorite, action: :create_favorite
    delete :favorite, action: :delete_favorite
    get :favorites
  end
end

这将为您提供两条路线:/listings/:id/favorite(用于创建-POST-和删除-DELETE-)和/listings/:id/favorites(GET)。创建和删除将是相同的favorite_listing_path(listing)(或类似的,请选中rake routes)。

现在,在您的ListingsController上定义以下操作:

class ListingsController < ApplicationController
  def create_favorite
    Listing.find(:id).favorites.create(user: current_user)
    redirect_to :something, notice: 'Favorited'
  end

  def delete_favorite
    Listing.find(id).favorites.where(user: current_user).destroy_all
    redirect_to :something, notice: 'Unfavorited'
  end

  def favorites
    @favorites = Listing.find(id).favorites
  end

  # of course, you could add a before_action to DRY it, I just wanted to be explicit on which is the actual resource
end