试图弄清楚如何在表单中设置关联。
我有三种型号:
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记录——在用户的Answer
和他正在查看的Request
之间创建关联。
我现在这样做的方法是:我在Request#Show
上闪烁request_id
值,然后当用户链接到Answer#new
时,它将闪烁的值传递到Answer#new上的隐藏表单标记中。这似乎不是最好的方法。
有什么想法吗?
使用flash的创造性方法值得称赞,但你的权利有一个简单的方法。您可以在控制器之间传递参数,就像使用路由名称在方法之间传递参数一样。
我没有完全理解你在这种情况下想要实现的目标,但看起来这里的博客应该让你开始。。
https://agilewarrior.wordpress.com/2013/08/31/how-to-pass-parameters-as-part-of-the-url-in-rails/
祝你好运!
从
Request#Show
到Answer#new
的用户链接
这可以通过sessions
或nested resources
(或两者都可以!)来实现。让我解释一下:
我肯定会在您的requests
路由中添加嵌套资源:
#config/routes.rb
resources :requests do
resources :answers, only: [:new, :create] #-> url.com/requests/:request_id/answers [POST]
end
这使您能够调用"嵌套"路由(IE路由,它将数据发送到子控制器,并要求将"父"数据附加到请求中)。
在您的情况下,您希望为请求创建答案。最有效的方法是使用如上所述的路由结构;这将允许您使用以下控制器方法:
#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
方法。如果你想要它,用上面的结构可以很容易地处理它。
传递用户有点棘手。
您可以使用路由,或者设置会话。
我会亲自设置一个会话(它更干净):
#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
对象中可用(这意味着您不必设置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
类似的东西对我有用:
- 我有两个模型(Formula和FormulaMaterial)
- Formula有许多FormulaMaterials,属于Formula
-
我的公式控制器设置@公式如下:
@formula=formula.fund(params[:id])
-
我在Formula show.html.erb中列出了我的Formula Materials,方法是在我的Formum控制器中这样声明:
@formula_materials=FormulaMaterial.其中(: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的新.html.erb时,我的URL看起来是这样的:
http://localhost:3000/formula_materials/new?formula_id=2
-
在我的FormulaMaterial new.html.erb文件中,我创建了一个hidden_field,通过使用"params"访问URL中的formula_id来设置关联的值,如下所示:
params[:formula_id]%>
我不确定这是否是最好的方法,但这种方法允许我每次都将上一页的视图id作为隐藏、关联和设置字段在表单中传递。
希望这能有所帮助!