我有三个实体:用户,联系人和订婚。 user
has_many: contacts
。联系belongs_to: user
。用户与联系人进行交互。我还有一个参与belongs_to: contact
。
在我的views/contacts/show.html.erb
我希望展示特定联系人页面,并让用户通过填写参与表单来注册与联系人的互动。我希望在联系人页面上创建的参与度与该特定联系人相关联。
所以我展示了一个联系人:
resources :contacts
resources :engagements, only: [:create, :edit, :destroy]
class ContactsController < ApplicationController
include ApplicationHelper
def show
@contact = Contact.find(params[:id])
set_current_contact @contact.id #pass the particular id to helper
end
end
在帮助器中定义方法:
module ApplicationHelper
def set_current_contact(contact_id)
@current_contact = Contact.find_by(id: contact_id)
end
def the_current_contact
@current_contact #create instance variable for the other helper
end
end
我要做的关键是让参与控制器知道&#39;联系用户正在注册订婚。即将@contact
传递给EngagementsController
class EngagementsController < ApplicationController
def create
@engagement = the_current_contact.engagements.build(engagement_params)
end
end
我收到错误:
undefined method `set_current_contact' for #<EngagementsController:0x007f2c2c24f360>
第一个问题是我不明白为什么控制器无法从ApplicationHelper
访问方法?
我不是故意问两个不同的问题,但第二个问题是以这种方式使用帮助是否是正确的方法。我知道HTTP是一种无状态协议,在这种情况下,帮助程序对于传递实例变量非常有用。我搜索了类似的帖子并找到了相关的Rails: Set a common instance variable across several controller actions但是虽然它推荐帮助者作为解决方案,但它没有特别解释如何使用帮助器。
编辑:我在include ApplicationHelper
中添加了遗失的EngagementsController
。现在错误是:
wrong number of arguments (given 0, expected 1)
Extracted source (around line #13):
end
13 def set_current_contact(contact_id)
14 @current_contact = Contact.find_by(id: contact_id)
15 end
答案 0 :(得分:1)
您无法使用实例变量在两个请求之间共享数据,甚至不能在对同一控制器的两个请求之间共享数据。 Rails creates a new controller instance for every request。即便如此,您的应用可能会在负载均衡器后面,并且没有人可以保证第二个请求甚至可以由同一服务器提供服务。
实现目标的最佳方法是将contact_id作为参数传递给EngagementsController#create
操作。或者使用会话数据。
答案 1 :(得分:0)
我找到了一种方法,contact_id
可以访问EngagementsController
,而无需通过帮助程序将变量从ContactsController
传递到EngagementsController
。嵌套资源:
resources :contacts do
resources :engagements
end
生成路径:
POST /contacts/:contact_id/engagements(.:format) engagements#create
因此,EngagementsController
:
def create
@contact = Contact.find(params[:contact_id])
@engagement = @contact.engagements.build(engagement_params)
end