2013-08-30 46 views
1

我正試圖讓Globalize3在我的應用程序上工作。我有博客帖子的玩具項目,我想翻譯。form_for混合id和區域設置參數

我的網址是這樣的:localhost/en/postslocalhost/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]

我的問題是:爲什麼它會這樣做,如何修復thix?


我已經嘗試過像改變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/} 
+0

你能顯示耙路線的輸出嗎?你說你在編輯時遇到這個錯誤?您點擊哪個鏈接進入編輯頁面? – dax

回答

4

這也許一些額外的工作,但仍然是一個公認的模式有一個單獨的形式容器爲新編輯的動作,比如這個:

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| %> 

注:我不太確定的區域設置的寶石是如何工作的,所以我排除以上...但是如果你確實需要明確包含語言環境,你可以使用例如post_path(@post, locale: params[:locale])。回想一下,post_path(@post)實際上是post_path(id: @post)的簡稱。也就是說,如果沒有明確說明,那麼您傳遞給指定路由的參數的順序與您的路由期望的相同。

+0

第一個解決方案運行良好,謝謝。 – Pacane

+0

考慮到如果由於某種原因你不使用'resources:entity',你可能在你的路由中有一些東西像'get'/ entities /:entity_id/edit',:to =>'entities#edit''這樣你的'form_for'中的url應該看起來像:'entity_path(entity_id:@post)'。非常好的解決方案謝謝你! – unmultimedio