Rails中的路由与Controller / action / id路由有问题

时间:2015-08-10 23:08:10

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

在我的Rails 4应用程序中,我通过PagesController创建页面以形成菜单。该菜单包含指向相应控制器的redirect_to索引操作的链接。该页面模型的列是:id,:title,:access_level,:html(实际上是指控制器),:icon

示例数据是:5,员工,3,员工,用户

注意:代码的不相关部分,例如"资源:员工"不可见!

路由文件:

resources :pages
resources :access

PagesController:

def show
  @pages = Page.find(params[:id])
  redirect_to controller: "#{@page.html}", action: "index"
end

阻止生成链接

<% @pages = Page.all %>
<% @pages.each do |page| %>
<li>
    <%= link_to({ controller: "pages", action: "show", id: "#{page.id}" }) do %><i class="fa fa-<%= page.icon %> fa-fw"></i> <%= page.title %>
    <% end %>
</li>
<% end %>

HTML基于示例生成link_to:

<a href="/pages/5"><i class="fa fa-users fa-fw"></i> Employees</a>

一切正常,除非我尝试实现基本登录系统但遇到以下错误:

ActionController::UrlGenerationError in Access#index
Showing C:/Users/Samsung/Documents/rails/AjansTakip/app/views/access/index.html.erb where line #9 raised:

No route matches {:action=>"attempt_login", :controller=>"access"}

Index.html.erb访问视图的第9行

<%= form_for :access, url: {action: "attempt_login"} do |f| %>

AccessController(:id_number是identify_number的缩写,与id无关)

def attempt_login
    if params[:id_number].present? && params[:password].present?
        found_user = Employee.where(id_number: params[:id_number]).first
        if found_user
            authorized_user = found_user.authenticate(params[:password])
        end
    end
    if authorized_user
        redirect_to controller: 'pages', action: 'index'
    else
        redirect_to action: 'login'
    end
  end

我正在关注Lynda Rails 4基本培训,我无法通过基本登录系统的第一部分实施,因此请不要评论除路由之外的任何编码部分,因为我试图在我的自己的。

就解决方案而言,我试过这个解决方案,将错误传递给另一个

get 'access/attempt_login', to: 'access#attempt_login'

但我很确定有更好的方法来处理这种情况。 当我通过index.html.erb上的帖子提交表单时,我收到另一个错误:

No route matches [POST] "/access/attempt_login"

我认为问题出现是因为默认路由是:controller(/:id(/:action))并且控制器在:action之前需要:id。我认为路由没有意义&#34; get&#34;适用于所有不需要的行为:id。

我使用的另一个解决方案是将默认路由更改为&#34;:controller(/:action(/:id))&#34;但这会导致更多的问题而不是解决(我们甚至可能会说它根本没有解决任何问题)。甚至菜单中的链接都会中断,因为link_to:action&#34; show&#34;不会被解析为href =&#34; pages / show / 5&#34;。我还尝试生成链接为link_to({控制器:&#34;页面&#34;,操作:&#34;显示&#34;,ID:&#34; 显示/ #{页面。 id}&#34;})但这不像我想要的那样实用和动态。

请指出正确的方向。我也愿意改变Paging如何与PagesController一起工作,我想不出更好的方法将页面存储在数据库中并将它们全部重定向到一个地方。

由于

1 个答案:

答案 0 :(得分:3)

是的,不要使用默认的控制器,那是旧学校。相反,试一试:

删除获取行:

get 'access#attempt_login', to: 'access#attempt_login'

现在,既然你想要它在资源的集合上,试试这个:

resources :access do
  collection do
    get :attempt_login
  end
end

然后以你的形式:

 <%= form_tag attempt_login_access_path, method: :get do |f| %>

对于创建或更新操作的网址,我使用form_tag。当你有模特出席时,Form_for很好。方法get也很重要,因为表单默认发布。您可能需要仔细检查该路径路径:

bundle exec rake routes | grep attempt

确保方法正确。