使用FreindlyID时创建自定义路径助手

时间:2013-12-12 02:16:29

标签: ruby-on-rails-3 routing override friendly-id

我们试图让我们的网站拥有更少的可擦除和更易读的网址 所以例如 www.loomio.org/discussions/3122 变 www.loomio.org/d/3saA4ds9/lets-go-to-the-moon 我们只想在show-links上使用人类可读的slug,所以www.loomio.org/d/3saA4ds9/edit应该是编辑讨论的网址

到目前为止,解决方案遵循以下最佳答案: Ruby on Rails: How to override the 'show' route of a resource?

修改routes.rb

  get '/d/:id/:slug', to: 'discussions#show', as: :discussion
  resources :discussions, path: 'd', except: [:edit, :show] do
    get :activity_counts, on: :collection
    member do
      post :update_description
      post :add_comment
      post :show_description_history
      get :new_proposal
      post :edit_title
      put :move
    end
  end

安装gem FriendlyID;在讨论表上创建并填充:key列;将以下内容添加到discussion.rb(模型):

  KEY_LENGTH = 10  
  extend FriendlyId  
  friendly_id :key

为group_path编写自定义路径帮助程序。在groups_helper.rb

def group_url(group, options={})
  url_for(options.merge(:controller => 'groups', :action => 'show',
                        :id => group.key, :slug => group.full_name.parameterize))
end

def group_path(group, options={})
  group_url(group, options.merge(:only_path => true))
end

rake路线产生:        group GET /g/:id/:slug(.:format)groups#show

虽然在某些情况下调用group_path(group)似乎有效,但我也看到了生成奇怪的无关网址,例如: http://loomio.org/group_requests/TegFOIx4DB/start_new_group?action=show&controller=groups%2Fgroups&slug=19-tory

在控制台中,我也遇到了错误,例如:

[5] pry(main)> g = Group.last
[6] pry(main)> app.group_path(g)
ActionController::RoutingError: No route matches {:controller=>"groups", :action=>"show", :id=>#<Group id: 2811, name: "Sylvester Buckridge", created_at: "2013-12-10 06:25:42", updated_at: "2013-12-10 06:25:42", privacy: "public", members_invitable_by: "members", parent_id: nil, email_new_motion: true, hide_members: false, beta_features: false, description: "A description for this group", memberships_count: 1, archived_at: nil, max_size: 300, cannot_contribute: false, distribution_metric: nil, sectors: nil, other_sector: nil, discussions_count: 0, motions_count: 0, country_name: nil, setup_completed_at: "2013-12-10 05:25:01", next_steps_completed: false, full_name: "Sylvester Buckridge", payment_plan: "undetermined", viewable_by_parent_members: false, key: "rkdlTytOin">}
from /home/s01us/.rvm/gems/ruby-2.0.0-p247/gems/actionpack-3.2.16/lib/action_dispatch/routing/route_set.rb:540:in `raise_routing_error'

我已尝试将ApplicationControllerApplicationHelper中的group_path和grop_url方法无效。

调用

group_path( group.key, group.fullname.parameterize ) 

有效,但理想情况下只需要打电话就可以了。

group_path(@group)

1 个答案:

答案 0 :(得分:3)

就我理解的问题而言,你可以使用好的老黑客在你的模型上定义to_param方法

class Group < ActiveRecord::Base
  def to_param
    "#{id}-#{slug}"
  end
end

这个解决方案的优点是你不需要做任何其他事情。当Rails从记录生成URL时,它会自动使用to_param方法作为记录ID。你可以做任何事情

redirect_to group_path(@group)
redirect_to @grup
# etc

并且你的Group.find应该吃它123-smth-smth,通常它足够聪明,可以提取id的整数部分