论坛首页 编程语言技术论坛

关于Rails中不可数名词的rest模型解决方法的一个实例

浏览 3631 次
精华帖 (0) :: 良好帖 (4) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-07-28  
之前看过论坛里的解决方案(http://www.iteye.com/post/524927),也Google了一下,发现没有一种办法可以完全解决所有问题,写得不够详尽,在此写了一个实例。

试验环境:
Ubuntu 8.04 / Ruby 1.8.6 / gem 1.2.0 / Rails 2.1.0 / MySQL 5.0
Windows XP SP2 / Ruby 1.8.6 / gem 1.2.0 / Rails 2.1.0 / SQLite3

运行命令:
rails fish #Windows下加-d mysql
ruby script/generate scaffold Fish name:string color:string
#Windows 下运行 rake db:create
rake db:migrate
ruby script/server


服务器启动正常,访问http://localhost:3000/fish,该页面正常,但是create fish出错。

办法1:
参考Quake Wang的办法,
map.resources :news, :singular => 'news'

修改Route的配置如下
map.resources :fish, :singular => 'fish'

没有解决问题,不知道当时的环境是什么,用的什么版本。

方法2:
参考google的方法:
修改Route的配置如下
map.resources :fish, :singular => 'fish_instance'

然后修改相应的URL,
index.html.erb中修改四处:
<h1>Listing fish</h1>

<table>
  <tr>
    <th>Name</th>
    <th>Color</th>
  </tr>

<% for fish in @fish %>
  <tr>
    <td><%=h fish.name %></td>
    <td><%=h fish.color %></td>
    <td><%= link_to 'Show', fish_instance_path(fish) %></td>
    <td><%= link_to 'Edit', edit_fish_instance_path(fish) %></td>
    <td><%= link_to 'Destroy', fish_instance_path(fish), :confirm => 'Are you sure?', :method => :delete %></td>
  </tr>
<% end %>
</table>

<br />

<%= link_to 'New fish', new_fish_instance_path %>

show.html.erb中修改一处:
<p>
  <b>Name:</b>
  <%=h @fish.name %>
</p>

<p>
  <b>Color:</b>
  <%=h @fish.color %>
</p>


<%= link_to 'Edit', edit_fish_instance_path(@fish) %> |
<%= link_to 'Back', fish_path %>

edit.html.erb中修改两处:
这里需要注意的是form_for的url的写法,很多文章里并没有提到就是,我开始也就是卡在这里。
<h1>Editing fish</h1>

<% form_for(@fish, :url => fish_instance_url(@fish)) do |f| %>
  <%= f.error_messages %>

  <p>
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </p>
  <p>
    <%= f.label :color %><br />
    <%= f.text_field :color %>
  </p>
  <p>
    <%= f.submit "Update" %>
  </p>
<% end %>

<%= link_to 'Show', fish_instance_path(@fish) %> |
<%= link_to 'Back', fish_path %>


fish_controller.rb中修改两处(只针对html):
redirect_to(fish_instance_path(@fish))

但是觉得这种办法并不是Rails提供的最佳解决办法,不知道是否有更为简洁的办法。
   发表时间:2008-07-28  
试试在初始化时

Inflector.inflections do |inflect|
   inflect.irregular 'person', 'people'
   inflect.uncountable %w( fish sheep )
end
0 请登录后投票
   发表时间:2008-07-28  
用方法一的话,自动生成的fish_path会有index和instance path的冲突。
你可以使用fish_index_path和fish_path(@fish)来区别。

在New页面,将fish_path改成fish_index_path即可
<% form_for(@fish, :url => fish_index_path) do |f| %>
<%= link_to 'Back', fish_index_path %>


我的试验环境:
Ubuntu 7.10 / Rails 2.1.0

p.s 你可以使用rake routes命令来查看RESTful resource生成的path有哪些
1 请登录后投票
   发表时间:2008-07-28  
caryl 写道
试试在初始化时

Inflector.inflections do |inflect|
   inflect.irregular 'person', 'people'
   inflect.uncountable %w( fish sheep )
end


已经试过了,按照inflections.rb注释的意思,fish是不用设置的。
# Be sure to restart your server when you modify this file.

# Add new inflection rules using the following format 
# (all these examples are active by default):
# Inflector.inflections do |inflect|
#   inflect.plural /^(ox)$/i, '\1en'
#   inflect.singular /^(ox)en/i, '\1'
#   inflect.irregular 'person', 'people'
#   inflect.uncountable %w( fish sheep )
# end
0 请登录后投票
   发表时间:2008-07-28  
Quake Wang 写道
用方法一的话,自动生成的fish_path会有index和instance path的冲突。
你可以使用fish_index_path和fish_path(@fish)来区别。

在New页面,将fish_path改成fish_index_path即可
<% form_for(@fish, :url => fish_index_path) do |f| %>
<%= link_to 'Back', fish_index_path %>


我的试验环境:
Ubuntu 7.10 / Rails 2.1.0

p.s 你可以使用rake routes命令来查看RESTful resource生成的path有哪些



我采用了你提到的modelname_index_path,发现很好用,分两个步骤:
(1)声明单复数形式,如果符合Rails已声明的规则,那么不需要再声明。
可以在%RAILS_APP_ROOT%/config/routes.rb中定义,使用singular参数,也可以在%RAILS_APP_ROOT%/config/initializers/inflections.rb文件中声明,后者好像是官方推崇的方式。
默认规则文件为:
%RUBY_ROOT_PATH%\lib\ruby\gems\1.8\gems\activesupport-2.1.0\lib\active_support\inflections.rb


(2)修改modelname_controlles.rb/new.html.erb/show.html.erb/edit.html.erb中的modelname_pathmodelname_index_path,修改new.html.erb中的
<% form_for(@modelname) do |f| %>


<% form_for(@modelname, :url => modelname_index_path) do |f| %>



btw, Rails中默认内置了一些名词的单复数形式,默认支持的不规则和不可数词有
  inflect.irregular('person', 'people')
  inflect.irregular('man', 'men')
  inflect.irregular('child', 'children')
  inflect.irregular('sex', 'sexes')
  inflect.irregular('move', 'moves')
  inflect.irregular('cow', 'kine')

  inflect.uncountable(%w(equipment information rice money species series fish sheep))

发现news这个词被这样支持
  inflect.singular(/(n)ews$/i, '\1ews')

0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics