我有一个订阅表单,我试图设置用户选择的计划,他们想要与订阅关联的业务和付款详细信息。在我的表单中,我使用select标签显示所有商家的列表,并在我的视图中正确显示,但保存后我收到以下错误:
undefined method `map' for #<Business:0x007f8ea7955b90>
new.html.erb
<div class="field">
<%= select_tag :business_id, options_from_collection_for_select(@businesses, "id", "name") %>
</div>
subscriptions_controller.rb
...
def new
@subscription = Subscription.new
@plan = Plan.find(params["plan_id"])
@businesses = Business.all
end
def create
@subscription = Subscription.new(subscription_params)
raise "Please, check subscription errors" unless @subscription.valid?
@subscription.process_payment
@subscription.save
redirect_to @subscription, notice: 'Subscription was successfully created.'
rescue => e
flash[:error] = e.message
render :new
end
private
def set_subscription
@subscription = Subscription.find(params[:id])
end
def subscription_params
params.require(:subscription).permit(:plan_id, :business_id, :card_token, :coupon)
end
我是否正确设置了select_tag?我需要修复我的创建方法吗?在SO上看其他解决方案但收效甚微。
答案 0 :(得分:0)
Rails为每个请求实例化一个新控制器。有一些关于here的信息。
这意味着当您在new
处理POST时,您在create
中设置的所有实例变量都将无法使用。
在您的情况下,当新订阅验证失败时,您将在:new
操作的急救块中呈现create
模板。您此时只会收到错误,而不是在您最初访问表单时。
问题是render :new
没有调用new
操作;它只是渲染模板。如果订阅未通过验证并且表单被重新呈现,则此控制器实例从未调用new
操作,并且实例变量没有模板预期的值。
尝试使用此代替render :new
:
redirect_to new_subscription_url
这将实例化一个新的控制器并调用new
动作,这样你就可以重新开始。在呈现模板之前,new
模板中所需的实例变量将被赋予正确的值。
作为替代方案,您可以在救援区中设置实例变量:
def create
...
rescue => e
flash[:error] = e.message
@businesses = Business.all
render :new
end
这是Stack Overflow上类似的question。
希望有所帮助。快乐的编码!