尝试让两个操作具有不同的视图,但具有相同的URL

时间:2017-01-06 22:26:47

标签: ruby-on-rails

我有牧羊人(即用户)的应用程序,每个牧羊人都有一套动物。我试图这样做,以便如果登录的牧羊人试图查看他们的一只动物,它会将它们带到由编辑动作控制的视图。或者,如果牧羊人试图观察另一只牧羊人的动物,它会给他们一个由表演动作控制的视野。我更喜欢没有*/edit的网址 - 我希望它们看起来与编辑和展示相同。在我的routes.rb文件中,我有这个......

get '/shepherds/:username/:eartag', to: 'animals#show', as: :shepherd_animal_show
get '/shepherds/:username/:eartag', to: 'animals#edit', as: :shepherd_animal_edit

在牧羊人的节目视图中,我创建了这样的动物链接......

<% if animal.shepherd == current_shepherd %>
    <a href="<%= shepherd_animal_edit_path(username: animal.shepherd.username, eartag: animal.eartag) %>"
<% else %>
    <a href="<%= shepherd_animal_show_path(username: animal.shepherd.username, eartag: animal.eartag) %>"
<% end %>

我可以看到,当我登录并尝试访问我的动物时,它会使用shepherd_animal_edit_path进入该区块,但它会将我引导至显示视图而不是编辑视图。这是路线输出的一部分......

shepherd_animal_show GET    /shepherds/:username/:eartag(.:format)  animals#show
shepherd_animal_edit GET    /shepherds/:username/:eartag(.:format)  animals#edit

我是Rails的初学者,非常感谢人们提供的任何帮助。

1 个答案:

答案 0 :(得分:1)

我认为您应该对两者使用show操作,并根据动物所有权呈现不同的模板。即:

def show
  ...
  render 'edit' if animal.shepherd == current_shepherd
  # the show template will be rendered automatically if `render` wasn't explicitly called
end

然后在您的视图中,您可以无条件地链接到show动作,控制器将负责决定要渲染的视图模板。

另外,FWIW,我可能会按如下方式定义路线:

resources :shepherds, shallow: true do
  resources :animals
end

然后在视图中使用link_to帮助程序而不是硬编码HTML标记:

<%= link_to animal_path(animal) %>

但那会让你做其他事情:

link_to shepherd_animals_path(@shepherd) # link to the `index` action of `AnimalsController`, with `params[:shepherd_id]` set to `@shepherd.id`. 

然后,如果current_shepherd.id == params[:shepherd_id](或current_shepherd == Shepherd.find(params[:shepherd_id])),则允许您渲染(或不渲染)牧羊人管理他/她自己的羊群的其他控件。