How do I pass a local variable from a form_for helper to a js file?
I have the following file called _subscribe.html.erb
<%= form_for @subscription, :url => {:controller => "subscriptions", :action => "create"} do |f| %>
<div><%= hidden_field_tag :group_id, group.id %></div>
<%= f.submit "Subscribe", class: "btn btn-primary subscribe_btn" %>
<% end %>
The group local variable gets passed from a do block into this form and works (html only up until now). I want to turn this into an ajax call so i added remote: true
to the form and added the file create.js.erb to the subscriptions folder:
$("#new_subscription").html("<%= escape_javascript(render('subscriptions/unsubscribe', locals: { group: group } )) %>")
and this is my subscriptions controller create action:
def create
@subscription = current_user.subscriptions.create(:group_id => params[:group_id])
@subscription.save
respond_to do |format|
format.html { redirect_to groups_path, flash[:success] = "You have successfully subscribed to this group" }
format.js
end
end
However now I get this error:
ActionView::Template::Error (undefined local variable or method `group' for #<#<Class:0x007fe7ecfd4950>:0x007fe7ecfde7e8>):
1: $("#new_subscription").html("<%= escape_javascript(render('subscriptions/unsubscribe', locals: { group: group } )) %>")
app/views/subscriptions/create.js.erb:1:in `_app_views_subscriptions_create_js_erb__3184685282411376061_70317032458920'
app/controllers/subscriptions_controller.rb:8:in `create'
The group local variable is not being passed from the form_for to the create.js.erb on submit. I have tried everything in the past 4 hours but am still coming up short. How do I fix this issue and pass the local variable from the _subscribe.html.erb partial to the create.js.erb file?
Edit:
More code... first my subscriptions controller create action:
def create
@group = Group.find(params[:group_id])
@subscription = current_user.subscriptions.create(:group_id => @group.id)
@subscription.save
respond_to do |format|
format.html { redirect_to groups_path }
format.js
end
end
and destroy action:
def destroy
@group = Group.find(params[:id])
@subscription = current_user.subscriptions.find_by(group_id: @group.id)
@subscription.destroy
respond_to do |format|
format.html { redirect_to groups_path }
format.js
end
end
& create.js.erb
$("#subscribe_button").html("<%= escape_javascript(render('subscriptions/unsubscribe', locals: { group: @group } )) %>")
& destory.js.erb
$("#unsubscribe_button").html("<%= escape_javascript(render('subscriptions/subscribe', locals: { group: @group } )) %>")
I am still getting the following error in the logs:
Started POST "/subscriptions" for 127.0.0.1 at 2014-11-20 22:23:39 +0000
Processing by SubscriptionsController#create as JS
Parameters: {"utf8"=>"✓", "group_id"=>"1", "commit"=>"Subscribe"}
User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = 'b0afd34150d0c021a1e4d0dfa357107a2aa59f00' LIMIT 1
Group Load (0.4ms) SELECT "groups".* FROM "groups" WHERE "groups"."id" = $1 LIMIT 1 [["id", "1"]]
(0.2ms) BEGIN
Subscription Exists (0.6ms) SELECT 1 AS one FROM "subscriptions" WHERE ("subscriptions"."group_id" = 1 AND "subscriptions"."user_id" = 2) LIMIT 1
SQL (0.6ms) INSERT INTO "subscriptions" ("created_at", "group_id", "role", "updated_at", "user_id") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["created_at", Thu, 20 Nov 2014 22:23:39 UTC +00:00], ["group_id", 1], ["role", "pending"], ["updated_at", Thu, 20 Nov 2014 22:23:39 UTC +00:00], ["user_id", 2]]
(0.4ms) COMMIT
(0.1ms) BEGIN
Subscription Exists (0.7ms) SELECT 1 AS one FROM "subscriptions" WHERE ("subscriptions"."group_id" = 1 AND "subscriptions"."id" != 96 AND "subscriptions"."user_id" = 2) LIMIT 1
(0.2ms) COMMIT
Rendered subscriptions/_unsubscribe.html.erb (100.3ms)
Rendered subscriptions/create.js.erb (101.7ms)
Completed 500 Internal Server Error in 120ms
ActionView::Template::Error (undefined local variable or method `group' for #<#<Class:0x007fdc05a244a8>:0x007fdc0545b350>):
1: <%= debug group %>
2: <div id="unsubscribe_button">
3: <%= button_to "Unsubscribe", subscription_path(group), :remote => true, :method => 'delete', class: "btn subscribe_btn" %>
4: </div>
app/views/subscriptions/_unsubscribe.html.erb:1:in `_app_views_subscriptions__unsubscribe_html_erb__4479900334468069300_70291478478720'
app/views/subscriptions/create.js.erb:1:in `_app_views_subscriptions_create_js_erb__1667797080065562395_70291478425360'
app/controllers/subscriptions_controller.rb:8:in `create'
You can clearly see that the @group is set in the create action and is successfully creating a subscription but the local variable is not being set in the js.erb files.
You don't. Execution ends when the current request ends, i.e. when the form is rendered. The .js.erb view template is not called until the form is submitted, starting a new request.
You'll have to create an instance variable e.g. @group = however_you_get_the_group
in the controller's create action to make it visible to the .js.erb view, and reference as such: locals: { group: @group }
The problem is that when you are in the create
action, you don't have the variables that you set in the previous action.
So you need to set again the @group
instance variable and then use it in your create.js.erb
template.
def create
@group = Group.find(params[:group_id])
@subscription = current_user.subscriptions.create(:group_id => @group.id)
@subscription.save
respond_to do |format|
format.html { redirect_to groups_path, flash[:success] = "You have successfully subscribed to this group" }
format.js
end
end
$("#new_subscription").html("<%= escape_javascript(render('subscriptions/unsubscribe', locals: { group: @group } )) %>")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With