【问题标题】:Rails Form Associations - Passing id From Previous PageRails 表单关联 - 从上一页传递 id
【发布时间】:2015-11-10 08:03:46
【问题描述】:

试图弄清楚我们如何在表单中建立关联。

我有 3 个模型:

class Request < ActiveRecord::Base
  has many :answers
  has many :users, through: :answers
end

class Answer < ActiveRecord::Base
   belongs to :user
   belongs to :request
end

class User < ActiveRecord::Base
   has many :answers
   has many :requests, through: :answers
end

我想弄清楚:如何从Request#Show 获得一个指向Answer#new 的用户链接,然后创建一个从上一页传入Request#Show request_id 的答案记录 - 在用户的Answer 和他正在查看的Request

我现在这样做的方法是:我在Request#Show 上闪现request_id 值,然后当用户链接到Answer#new 时,它将闪现的值传递到Answer#new 上的隐藏表单标签中。这似乎不是最好的方法。

有什么想法吗?

【问题讨论】:

    标签: ruby-on-rails forms ruby-on-rails-4 associations model-associations


    【解决方案1】:

    感谢使用 Flash 的创意方法,但是您的权利有一个简单的方法。您可以在控制器之间传递很多参数,就像使用路由名称在方法之间传递参数一样。

    在这种情况下,我并没有完全理解你想要实现的目标,但看起来这个博客条目应该让你开始..

    https://agilewarrior.wordpress.com/2013/08/31/how-to-pass-parameters-as-part-of-the-url-in-rails/

    祝你好运!

    【讨论】:

      【解决方案2】:

      用户从Request#Show链接到Answer#new

      这可以通过sessionsnested resources(或两者兼有!)来实现。让我解释一下:


      我肯定会在您的requests 路由中添加一个嵌套资源

      #config/routes.rb
      resources :requests do
         resources :answers, only: [:new, :create] #-> url.com/requests/:request_id/answers [POST]
      end
      

      这使您能够调用“嵌套”路由(即向子控制器发送数据并要求将“父”数据附加到请求的 IE 路由)。

      在您的情况下,您想为 request 创建一个 answer。最有效的方法是使用如上的路由结构;这将允许您使用以下控制器方法:

      #app/controllers/answers_controller.rb
      class AnswersController < ApplicationController
         def new
            @request = Request.find params[:request_id]
            @answer = @request.answers.new
         end
      
         def create
            @request = Request.find params[:request_id]
            @answer = @request.answers.new answer_params
            @answer.save
         end
      
         private
      
         def answer_params
            params.require(:answer).permit(:title, :body)
         end
      end
      

      通过将request_id 传递给嵌套路由,您可以创建答案。您必须注意,相应的路由需要 POST 方法才能工作。

      您不需要new 方法。如果你想要的话,用上面的结构就可以轻松搞定。


      传递 user 有点棘手。

      你可以或者使用路由,或者设置一个会话

      我会亲自设置一个会话(它更干净):

      #app/controllers/requests_controller.rb
      class RequestsController < ApplicationController
         def show
            session[:user_id] = @user.id #-> I don't know how you populate @user
         end
      end
      

      这将使您能够在此处访问此会话:

      #app/controllers/answers_controller.rb
      class AnswersController < ApplicationController
         def new
            user = User.find session[:user_id]
         end
      end
      
      #app/views/requests/show.html.erb
      <%= link_to "New Answer", request_new_answer_path(request) %>
      

      --

      如果您使用Devise,用户对象应该在current_user object 中可用(这意味着您不必设置session[:user_id]):

      #app/controllers/answers_controller.rb
      class AnswersController < ApplicationController
         def new
            ## current_user available here if using devise
         end
      end
      

      要将@user 分配给新的answer 记录,只需在answers#create 中执行此操作:

      #app/controllers/answers_controller.rb
      class AnswersController < ApplicationController
         ...
      
         def create
            @request     = Request.find params[:request_id]
            @answer      = @request.answers.new answer_params
            @answer.user = current_user
            @answer.save
         end
      
      end
      

      【讨论】:

        【解决方案3】:

        这样的事情对我有用:

        • 我有两个模型(Formula 和 FormulaMaterial)
        • Formula has_many FormulaMaterials,属于Formula
        • 我的公式控制器像这样设置@formula:

          @formula = Formula.find(params[:id])

        • 我在我的 Formula show.html.erb 中列出我的 Formula Materials,方法是在我的 Formula 控制器中声明它,如下所示:

          @formula_materials = FormulaMaterial.where(:formula_id => @formula)

        • 当我想将新的 FormulaMaterial 添加到我的公式时,我的 show.html.erb 文件中的“新公式材料”按钮如下所示:

          <%= link_to 'Add Material To Formula', new_formula_material_path(:formula_id => @formula), class: "btn btn-success" %>
          
        • 在“new_..._path”中,我将关联的 id 设置为 @formula 变量。当它传递给我的 FormulaMaterial 的 new.html.erb 时,我的 URL 如下所示:

          http://localhost:3000/formula_materials/new?formula_id=2

        • 在我的 FormulaMaterial new.html.erb 文件中,我创建了一个 hidden_​​field,它通过使用“params”访问 URL 中的 formula_id 来设置关联的值,如下所示:

          参数[:formula_id] %>

        我不确定这是否是执行此操作的最佳方式,但这种方式允许我每次都将上一页中的视图 ID 作为表单中的隐藏、关联和设置字段传递。

        希望这会有所帮助!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-09-07
          • 1970-01-01
          • 1970-01-01
          • 2021-07-11
          • 1970-01-01
          • 2022-12-13
          • 1970-01-01
          相关资源
          最近更新 更多