【问题标题】:form_for and scopes, rails 3form_for 和范围,rails 3
【发布时间】:2010-09-18 14:03:45
【问题描述】:

由于范围和 rails 3 中的 form_for 助手,我遇到了问题。 路由 - 文件如下所示:

scope "(/:tab)" do
  resources :article
end

表单看起来像这样:

<%= form_for(@article) %>
   <%= f.label :title %>
   <%= f.text_field :title %>
    etc.
<%end%>

tab - 属性存储在 params[:tab] 中,作为一个字符串 我的问题是这会在表单中生成错误的 url。我怎样才能让它工作? 类型化的 url article_path(params[:tab], @article) 工作得很好

【问题讨论】:

    标签: scope ruby-on-rails-3 form-for


    【解决方案1】:

    我想出的答案很丑陋,但适用于更新和创建:

    <%= form_for(@article, :url => (@article.new_record? ? 
        articles_path(params[:tab]) : article_path(params[:tab], @article) do |f| %>
    

    更新: 更好的解决方案是将 default_url_options-method 覆盖为如下所示:

    def default_url_options(options={})
      { :tab => params[:tab] }
    end
    

    然后 可以使用,并且所有的url都正确生成了

    【讨论】:

    • 谢谢,我遇到了完全相同的问题,一直在寻找解决方案。我有点认为会有一个更优雅的解决方案。仅供参考,通过 rails 助手,它似乎更喜欢#persisted?到#new_record?,所以也许最好的做法是这样做:&lt;%= form_for(@article, :url =&gt; (@article.persisted? ? article_path(params[:tab], @article) : articles_path(params[:tab]) do |f| %&gt;
    • default_url_options 在控制器中,可以是私有的。
    【解决方案2】:

    试试:

    <%= form_for [:tab, @article] do |f| %>
       <%= f.label :title %>
       <%= f.text_field :title %>
        etc.
    <%end%>
    

    【讨论】:

    • 然后查找未定义的tab_article_path。
    • 你的 routes.rb 文件生成的路由是什么?在终端中尝试“$ rake routes”
    【解决方案3】:

    您可以明确指定路径:

    <%= form_for(@article, :url => article_path(@article, :tab => params[:tab]) %>
    

    【讨论】:

    • 这似乎在编辑部分工作得很好,但是如果我想对新建和编辑使用相同的表单,它会在 new 中失败并出现以下错误,因为新文章没有 id
    【解决方案4】:

    我对 form_for 和 scopes 的类似问题的解决方案是在 helpers/&lt;model_name&gt;/&lt;model_name&gt;_helper.rb 中定义新方法,例如我的是 sessions_helper.rb 其中包含

    module Implant::SessionsHelper
      def sessions_form_path(session)
        session.new_record? ? sessions_path : session_path(session)
      end
    end
    

    在我看来我做到了

    form_for(@session, url: sessions_form_path(@session)) do |f|
    

    有问题的 routes.rb 部分

    scope module: 'implant' do
      resources :sessions
    end
    

    ...要使用:tab 参数进行管理,您可以将其添加到辅助方法中。

    【讨论】:

      【解决方案5】:

      我发现这是一个非常烦人的问题,并且现在通过以下猴子补丁解决了这个问题。像这样的通用,它有点出价,因为你只是将整个参数包传递给 polymorphic_url,这是 form_for 在引擎盖下用来猜测路线的东西。更简洁的方法是仅合并范围值。

      我的解决方案:

      https://gist.github.com/1848467

      module ActionDispatch
        module Routing
          module PolymorphicRoutes
            def polymorphic_path(record_or_hash_or_array, options = {})
              begin
                  polymorphic_url(record_or_hash_or_array, options.merge(:routing_type => :path))
              rescue Exception => e
                  polymorphic_url(record_or_hash_or_array, options.merge(:routing_type => :path).merge(params.reject{|k,v| ["controller", "action"].include? k.to_s}))
              end
            end
          end
        end
      end
      

      【讨论】:

        【解决方案6】:

        在非常相似的情况下,我在如下路线中定义了范围:

        scope :path => ":election_id", :as => "election" do 
          resources :questions
        end
        

        现在我有了 election_questions_path(@election) 这样的助手

        在我可以使用的形式中:

        form_for [@election, @question] do |f|
          ...
        end
        

        在上述示例中,@election 是 Election 模型的一个实例。

        将 Friendly_id 集成到此解决方案后,我得到了一些漂亮的网址。例如“http://mydomain.com/elections-2012/questions/my-question”

        【讨论】:

          【解决方案7】:

          我不确定这可以追溯到多远,但它适用于 Rails 6。我使用:

          <%= form_for(@article, url: [@article, { tab: params[:tab] }]) %>
             <%= f.label :title %>
             <%= f.text_field :title %>
              etc.
          <% end %>
          

          这是因为数组 URL 生成语法。在new 的情况下,@article 被检测为未持久化并路由到POST 路由。在edit 的情况下,@article 被检测为被持久化并路由到带有 ID 的PUT 路由。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-11-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多