3

我正在尝试让 Globalize3 在我的应用程序上运行。我有博客文章的玩具项目,我想翻译。

我的网址如下所示:localhost/en/posts localhost/fr/posts

这是我在我的ApplicationController

before_action :set_locale

def set_locale
  I18n.locale = params[:locale] if params[:locale] || I18n.default_locale
end

我使用相同form_for的方法来创建和更新帖子。这是查看代码:

<%= form_for(@post) do |f| %>
...
<% end %>

当我转到/new页面时它工作正常,这是控制器代码:

def new                                    
  @post = Post.new                         
end   

def create                                 
  @post = Post.new(post_params)            

  if @post.save                            
    redirect_to action: :show, id: @post.id
  else                                     
    render 'new'                           
  end                                      
end    

但是当我尝试使用 url 编辑帖子时/en/posts/1/edit,它会混合传递给form_for. 那是错误信息:

没有路由匹配 {:action=>"show", :controller=>"posts", :locale=>#, :id=>nil, :format=>nil} 缺少必需的键:[:locale, :id]

我的问题是:为什么要这样做,我该如何解决?


我已经尝试过一些事情,比如将form_for声明更改为:

<%= form_for(@post, url: {action: 'show', id: @post, locale: params[:locale]} ) do |f| %>

所以它适用于update但不适用于new因为我的帖子没有id

No route matches {:action=>"show", :locale=>"en", :id=>#<Post id: nil, created_at: nil, updated_at: nil, title: nil, text: nil>, :controller=>"posts"}

所以,是的,如果我可以避免这样做,我真的不想使用 2 个表单来创建和更新。有没有这样做的好方法?

编辑:

这是我的耙子路线

   Prefix Verb   URI Pattern                       Controller#Action
    posts GET    /:locale/posts(.:format)          posts#index {:locale=>/en|fr/}
          POST   /:locale/posts(.:format)          posts#create {:locale=>/en|fr/}
 new_post GET    /:locale/posts/new(.:format)      posts#new {:locale=>/en|fr/}
edit_post GET    /:locale/posts/:id/edit(.:format) posts#edit {:locale=>/en|fr/}
     post GET    /:locale/posts/:id(.:format)      posts#show {:locale=>/en|fr/}
          PATCH  /:locale/posts/:id(.:format)      posts#update {:locale=>/en|fr/}
          PUT    /:locale/posts/:id(.:format)      posts#update {:locale=>/en|fr/}
          DELETE /:locale/posts/:id(.:format)      posts#destroy {:locale=>/en|fr/}
4

1 回答 1

6

为新操作和编辑操作提供单独的表单容器可能需要一些额外的工作,但仍然是一种公认​​的模式,例如:

new.html.erb

<%= form_for(@post, url: posts_path) do |f| %>
  <%= render 'form', f: f %>
  <%= f.submit 'Create' %>
<% end %>

edit.html.erb

<%= form_for(@post, url: post_path(@post)) do |f| %>
  <%= render 'form', f: f %>
  <%= f.submit 'Update' %>
<% end %>

所以这是一种选择。您在部分中呈现公共表单字段,_form.html.erb并在各自的表单容器中执行新/编辑的任何独特操作。

但是,如果您真的只想拥有一个表单容器文件,您可以随时这样做:

<%= form_for(@post, url: (@post.new_record? ? posts_path : post_path(@post)) ) do |f| %>

注意:我不确定 locales gem 是如何工作的,所以我在上面排除了它......但是如果你确实需要明确地包含语言环境,你可以使用 eg 来做到这一点post_path(@post, locale: params[:locale])。回想一下,这post_path(@post)实际上是post_path(id: @post). 也就是说,如果没有明确说明,您传递给命名路由的参数的顺序与您的路由期望的相同。

于 2013-08-30T14:50:03.557 回答