在我的应用中,硬币可能属于也可能不属于网络。因此,我在routes.rb
中有以下内容:
resources :coins
resources :networks do
resources :coins
end
您可以通过硬币关注coins
#关注并通过硬币取消关注#unfollow
这对于属于网络的硬币来说效果很好:
match 'networks/:network_id/coins/:id/follow', to: 'coins#follow', via: 'get', :as => :follow_coin
match 'networks/:network_id/coins/:id/unfollow', to: 'coins#unfollow', via: 'get', :as => :unfollow_coin
我也想这样做:
match 'coins/:id/follow', to: 'coins#follow', via: 'get', :as => :follow_coin
match '/coins/:id/unfollow', to: 'coins#unfollow', via: 'get', :as => :unfollow_coin
但访问coins/coinname
时出现此错误,例如:
Invalid route name, already in use: 'follow_coin' You may have defined two routes with the same name using the `:as` option, or you may be overriding a route already defined by a resource with the same naming.
我不清楚适当的解决方案是什么。我想将networks/:network_id/coins/:id/follow
和coins/:id/follow
映射到coins#follow
操作,该操作已准备好处理属于网络的硬币和不属于网络的硬币。
我怀疑即使是:
match 'networks/:network_id/coins/:id/follow', to: 'coins#follow', via: 'get', :as => :follow_coin
我可以使用networks
资源
答案 0 :(得分:1)
可以为不同的网址设置相同的controller#action
。
但它们应该有不同的route helper
,因此在rails视图或控制器中,我们可以为它们生成相应的URL。
将代码更改为此
match 'networks/:network_id/coins/:id/follow', to: 'coins#follow', via: 'get', :as => :network_follow_coin
match 'coins/:id/follow', to: 'coins#follow', via: 'get', :as => :follow_coin
因此,在使用network_follow_coin(network_id, coin_id)
时,会生成网址/networks/1/coins/2/follow
。
使用follow_coin_path(coin_id)
时,会生成网址/coins/2/follow
。
至于简化代码,你应该使用resource
来更好地包装和理解,减少match
的使用(实际上我认为永远不会)。改变这种方式
resource :networks do
resource :coins do
member do
put :follow
put :unfollow
end
end
end
另一件事是,如果您在数据库中更改某些内容,则不应将http method
设置为get
。如果是get
方法,则假设只获取数据,不进行修改。它也很危险,因为一些蜘蛛会访问您网站中的每个链接,它可能会激活一些不好的东西。
答案 1 :(得分:1)
除了seaify所说的(很棒的建议!),你可以这样做:
resource :coins do
member do
put :follow
put :unfollow
end
end
然后,当你想使用network_id
时,做一些类似的事情(假设你定义了@coin
变量):
follow_coin_path(network_id: network_id)
这会给你类似的东西:
/coins/2/follow?network_id=1
你的参数将是:
{..., id: 2, network_id: 1, ...}
因为听起来你已经有了确定network_id
参数是否存在的逻辑。
如果您尝试使用coinname
作为识别变量(而不是id
),请执行以下操作:
resources :coins, param: :coinname do
member do
put :follow
put :unfollow
end
end
执行rake routes
时,您会看到类似的内容:
follow_coin PUT /coins/:coinname/follow(.:format) coins#follow
unfollow_coin PUT /coins/:coinname/unfollow(.:format) coins#unfollow
coins GET /coins(.:format) coins#index
POST /coins(.:format) coins#create
new_coin GET /coins/new(.:format) coins#new
edit_coin GET /coins/:coinname/edit(.:format) coins#edit
coin GET /coins/:coinname(.:format) coins#show
PATCH /coins/:coinname(.:format) coins#update
PUT /coins/:coinname(.:format) coins#update
DELETE /coins/:coinname(.:format) coins#destroy
你的参数将包含类似的内容:
{..., coinname: 'bitcoin', ...}
此外,当您使用link_to
时,请记住:
link_to("Follow #{@coin.name}", follow_coin_path(@coin), method: :put)
如果您不使用method: :put
,则link_to
会生成get
。并且您最终会遇到No route matches [GET] "/coins/coinname/follow"
错误。