Replacing partial with AJAX in Rails 4: undefined method `id` - javascript

When replacing a partial through Ajax, one method is giving me the proper result but the other (almost identical) isn't. I want to select and deselect a group for a specific campaign. Selecting gives me a direct replacement, deselecting doesn't.
models/general_connection.rb
belongs_to :campaign
belongs_to :group
models/group.rb
has_many :general_connections
has_many :campaigns, through: :general_connections
models/campaign.rb
has_many :general_connections
has_many :groups, through: :general_connections
controllers/general_connection.rb
def connect_group_to_campaign
#group = Group.find(params[:group_id])
#campaign = Campaign.find(params[:campaign_id])
#campaign.general_connections.create(group: #group)
respond_to do |format|
format.html { redirect_to :back }
format.js
end
end
def disconnect_group_from_campaign
#general_connection = GeneralConnection.where("group_id = ? AND campaign_id = ?", params[:group_id], params[:campaign_id]).first
#group = #general_connection.group
#general_connection.destroy
respond_to do |format|
format.html { redirect_to :back }
format.js
end
end
views/campaign/show.html.erb
<div class="row">
<% #main_groups.each do |group| %>
<%= render partial: 'groups_form', locals: { group: group } %>
<% end %>
</div>
*views/campaign/_groups_form.html.erb
<div class="row" id="group_<%= group.id %>">
<div class="col m6">
<div class="valign-wrapper black-text">
<% if group.icon.nil? %>
<i class="material-icons">group</i>
<% else %>
<i class="material-icons"><%= group.icon %></i>
<% end %>
&nbsp<%= group.title %>
</div>
</div>
<div class="col m6">
<% if !grouped(group) %>
<%= form_tag connect_group_to_campaign_path(:group_id => group.id, :campaign_id => #campaign.id), remote: true do %>
<%= button_tag 'check_box_outline_blank', class: "secondary-content material-icons grey-text", style: "background-color:white;border:none;" %>
<% end %>
<% else %>
<%= form_tag disconnect_group_from_campaign_path(:group_id => group.id, :campaign_id => #campaign.id), remote: true do %>
<%= button_tag 'check_box', class: "secondary-content material-icons grey-text", style: "background-color:white;border:none;" %>
<% end %>
<% end %>
</div>
</div>
views/general_connection/connect_group_to_campaign.js.erb
$('#group_<%= #group.id %>').replaceWith('<%= j render partial: 'campaigns/groups_form', locals: {group: #group} %>');
views/general_connection/disconnect_group_from_campaign.js.erb
$('#group_<%= #group.id %>').replaceWith('<%= j render partial: 'campaigns/groups_form', locals: {group: #group} %>');
...and this is the error that I'm getting:
ActionView::Template::Error (undefined method `id' for nil:NilClass):
12: </div>
13: <div class="col m6">
14: <% if !grouped(group) %>
15: <%= form_tag connect_group_to_campaign_path(:group_id => group.id, :campaign_id => #campaign.id), remote: true do %>
16: <%= button_tag 'check_box_outline_blank', class: "secondary-content material-icons grey-text", style: "background-color:white;border:none;" %>
17: <% end %>
18: <% else %>
To sum it up: both methods are working, but only connect_group_to_campaign gives a direct result and disconnect_group_from_campaign doesn't and needs a browser refresh.
Can anyone help me out?

It seems #campaign object is not declared in disconnect_group_from_campaign method. Try it after adding the below line in your disconnect_group_from_campaign method
#campaign = Campaign.find(params[:campaign_id])

Related

Implementing AJAX Creation, Missing Template (Create) Error

I am trying to implement AJAX in my to do type app, but am getting a missing template error (Missing template items/create, application/create with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee]}.) on my create action. There shouldn't be a create.html.erb page because the creation of items happens on a lists#show page:
<div class='new-item'>
<%= render 'items/form' %>
</div>
<div class="js-items">
<% #items.each do |item| %>
<%= div_for(item) do %>
<p><%= link_to "", list_item_path(#list, item), method: :delete, remote: true, class: 'glyphicon glyphicon-ok', style: "margin-right: 10px" %>
<%= item.name %>
<% if item.delegated_to != "" && item.user_id == current_user.id %>
<small>(Delegated to <%= item.delegated_to %>)</small>
<% elsif item.delegated_to != "" && item.user_id != current_user.id %>
<small>(Delegated by <%= item.user_id %>)</small>
<% end %></p>
<% end %>
<% end %>
</div>
And the _form.html.erb partial to which it links:
<div class="row">
<div class="col-xs-12">
<%= form_for [#list, #item], remote: true do |f| %>
<div class="form-group col-sm-6">
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control', placeholder: "Enter Item Name" %>
</div>
<div class="form-group col-sm-6">
<%= f.label 'Delegate To (Not Required)' %>
<%= f.text_field :delegated_to, class: 'form-control', placeholder: "Enter an Email Address" %>
</div>
<div class="text-center"><%= f.submit "Add Item to List", class: 'btn btn-primary' %></div>
<% end %>
</div>
</div>
Here's the create method in the items_controller:
def create
#list = List.friendly.find(params[:list_id])
#item = #list.items.new(item_params)
#item.user = current_user
#new_item = Item.new
if #item.save
flash[:notice] = "Item saved successfully."
else
flash[:alert] = "Item failed to save."
end
respond_to do |format| <<<<ERROR CALLED ON THIS LINE
format.html
format.js
end
end
And here's my create.js.erb file:
<% if #item.valid? %>
$('.js-items').prepend("<%= escape_javascript(render(#item)) %>");
$('.new-item').html("<%= escape_javascript(render partial: 'items/form', locals: { list: #list, item: #new_item }) %>");
<% else %>
$('.flash').prepend("<div class='alert alert-danger'><button type='button' class='close' data-dismiss='alert'>×</button><%= flash.now[:alert] %></div>");
$('.new-item').html("<%= escape_javascript(render partial: 'items/form', locals: { list: #list, item: #item }) %>");
<% end %>
Anyone have any ideas why I am getting this? I tried removing the format.html line from the items_controller but I got an unrecognizable format error.
You can force the form submission to use a JS format, instead of the default HTML format, so that your respond_to block will render the create.js.erb view instead of the create.html.erb view.
<%= form_for([#list, #item], format: :js, remote: true) do |f| %>
Typically, Rails will detect your remote: true option via "unobtrusive JavaScript (ujs)", which will effectively handle the format: :js option for you. There is something unique in your setup that we have not identified, which is requiring you to enforce the format option.
To see that your create.js.erb is working, you can change the line that renders your item partial:
$('.js-items').prepend("<%= escape_javascript(render(#item)) %>");
To render a the item's name, wrapped in a <p> tag:
$('.js-items').prepend("<p>" + <%= #item.name %> + "</p>");
You can customize that line to generate the html that you want to appear for your new list item. Based on your code above, this looks like it will work out for you.
As you finish your to-do app, you can create a partial for your item, and then change that line again so that your partial will be appended to your list of items.

ajax call not updating content on rails

Im trying to implement a bit a Ajax into my app seems to work correctly but it isnt updating the page after the action is executed .
I added Ajax to my Destroy method
def destroy
#item = Item.find(params[:id])
#item.user = current_user
if #item.destroy
flash[:notice] = "Item Completed"
else
flash[:alert] = "Item was unable to be marked completed "
end
respond_to do |format|
format.html
format.js
end
end
i have update my _item.html.erb and _form.html.erb partials with remote: true
<%= content_tag :div, class: 'media', id: "item-#{item.id}" do %>
<div class="media">
<div class="media-body">
<small>
<%= item.name.titleize %>
| submitted <%= time_ago_in_words(item.created_at) %>
<% if current_user == #user %>
<%= link_to "Completed ", [#user, item], method: :delete,remote: true, class: 'glyphicon glyphicon-ok' %><br>
<% end %>
</small>
</div>
</div>
<% end %>
_from.html.erb
<%= form_for [#user, item ], remote: true do |f|%>
<div class="form-group">
<%= f.label :name, class: 'sr-only' %>
<%= f.text_field :name , class: 'form-control', placeholder: "Enter a new item " %>
</div>
<%= f.submit "Submit Item", class: 'btn btn-primary pull-right' %>
<% end %>
User#show view <div class='new_item'>
<%= render :partial => 'items/form', :locals =>{:item => Item.new} %>
</div>
<% end %>
<div class='js-items'>
<% #user.items.order('created_at DESC').each do |item| %>
<%= render :partial => 'items/item' , :locals => {:item => item } %>
</div>
destroy.js.erb
$('#item-<%= #item.id %>').hide();
Like I said before, the item is deleted when i click the delete button but i need to refresh the page in order to see the updated page. Any ideas what i might be doing wrong, any push to the right direction would be greatly appreciated!
Try rendering the java script in the method itself and check,
def destroy
#item = Item.find(params[:id])
#item.user = current_user
if #item.destroy
flash[:notice] = "Item Completed"
else
flash[:alert] = "Item was unable to be marked completed "
end
respond_to do |format|
format.html
format.js { render
$('#item-<%= #item.id %>').hide();
}
end
end

Rails & Zurb Modal Loads Entire Page On Edit

I'm trying to edit content from my rails app Products through a zurb foundation modal. I can add new just fine. But when trying click the edit button, it loads a modal with the whole page again. Although it loads the correct edit page, I just want an edit form. Not a whole new render of my site.
Products_controller.rb
class ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
# GET /products
# GET /products.json
def index
#products = Product.all
#product = Product.new
end
# GET /products/1
# GET /products/1.json
def show
end
# GET /products/new
def new
#product = Product.new
end
# GET /products/1/edit
def edit
#product = Product.find(params[:id])
end
# POST /products
# POST /products.json
def create
#product = Product.new(product_params)
respond_to do |format|
if #product.save
format.html { redirect_to #product, notice: 'Product was successfully created.' }
format.json { render :show, status: :created, location: #product }
else
format.html { render :new }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /products/1
# PATCH/PUT /products/1.json
def update
respond_to do |format|
if #product.update(product_params)
format.html { redirect_to #product, notice: 'Product was successfully updated.' }
format.json { render :show, status: :ok, location: #product }
else
format.html { render :edit }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
# DELETE /products/1
# DELETE /products/1.json
def destroy
#product.destroy
respond_to do |format|
format.html { redirect_to products_url, notice: 'Product was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_product
#product = Product.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def product_params
params.require(:product).permit(:name, :price)
end
end
index.html.erb
<h1>Listing products</h1>
Click Me For A Modal
<table>
<thead>
<tr>
<th>Name</th>
<th>Price</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #products.each do |product| %>
<tr>
<td><%= product.name %></td>
<td><%= product.price %></td>
<td><%= link_to 'Show', product %></td>
<td><%= link_to 'Edit', edit_product_path(product) %></td>
<td><%= link_to 'EditM', edit_product_path(product), :remote => true, class: "", "data-reveal-id" => "editModal", "data-reveal-ajax" => edit_product_path(product) %></td>
<td><%= link_to 'Destroy', product, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Product', new_product_path, class: "button radius", "data-reveal-id" => "addModal" %>
<div id="addModal" class="reveal-modal" data-reveal>
<%= render :partial => 'form', locals: { product: #products } %>
<a class="close-reveal-modal">×</a>
</div>
<div id="editModal" class="reveal-modal" data-reveal>
<%= render :partial => 'form' %>
<a class="close-reveal-modal">×</a>
</div>
_form.html.erb
<%= form_for(#product) do |f| %>
<% if #product.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#product.errors.count, "error") %> prohibited this product from being saved:</h2>
<ul>
<% #product.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="row">
<div class="small-3 columns">
<%= f.label :name, class: "right inline" %>
</div>
<div class="small-9 columns">
<%= f.text_field :name %>
</div>
</div>
<div class="row">
<div class="small-3 columns">
<%= f.label :price, class: "right inline", title: "Price In USD", data: { tooltip: true } %>
</div>
<div class="small-9 columns">
<%= f.text_field :price %>
</div>
</div>
<div class="row">
<div class="small-9 small-offset-3 columns">
<%= f.submit %>
</div>
</div>
<% end %>
Below is an image of how it loads after you select the EditM button.
I have updated my :edit method to the following. It appears to be working so it loads the action only, not the layout. Is this the proper way? Or should I be doing it differently?
def edit
#product = Product.find(params[:id])
render :layout => false
end
This is the modal in index.html.erb:
<div id="editModal" class="reveal-modal" data-reveal>
<a class="close-reveal-modal">×</a>
</div>

How to Include 2 Models in 1 Form?

One model creates :name, :metric (Quantified.rb), and the other creates :result_value, :result_date (Result.rb).
class Quantified < ActiveRecord::Base
belongs_to :user
scope :averaged, -> { where(categories: 'Monthly Average') }
scope :instance, -> { where(categories: 'One-Time Instance') }
has_many :results
CATEGORIES = ['Monthly Average', 'One-Time Instance']
end
class Result < ActiveRecord::Base
belongs_to :user
belongs_to :quantified
end
What do I need to do in the _form and/or controller that would allow a User to add his results_date & results_value (results _form) to a respective name and metric (quantifieds _form)?
<%= form_for(#quantified) do |f| %>
<% if #quantified.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#quantified.errors.count, "error") %> prohibited this quantified from being saved:</h2>
<ul>
<% #quantified.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="america">
<form>
<%= f.select :categories, Quantified::CATEGORIES %>
<br>
<br>
<div class="form-group">
<%= f.text_field :name, class: 'form-control', placeholder: 'Enter Name' %>
</div>
<div class="form-group">
<%= f.text_field :metric, class: 'form-control', placeholder: 'Enter Metric (i.e. Miles, Pounds, $, Subscribers)' %>
</div>
<div class="date-group">
<label> Date: </label>
<%= f.date_select :date, :order => [:month, :year], class: 'date-select' %>
</div>
<div class="america2">
<%= button_tag(type: 'submit', class: "btn") do %>
<span class="glyphicon glyphicon-plus"></span>
<% end %>
<%= link_to quantifieds_path, class: 'btn' do %>
<span class="glyphicon glyphicon-chevron-left"></span>
<% end %>
<%= link_to #quantified, method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn' do %>
<span class="glyphicon glyphicon-trash"></span>
<% end %>
</div>
</form>
</div>
<% end %>
<%= form_for(#result) do |f| %>
<% if #result.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#result.errors.count, "error") %> prohibited this result from being saved:</h2>
<ul>
<% #result.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="america">
<form>
<div class="form-group">
<%= f.text_field :result_value, class: 'form-control', placeholder: 'Enter Result' %>
</div>
<div class="date-group">
<label> Date: </label>
<%= f.date_select :result_date, :order => [:month, :year], class: 'date-select' %>
</div>
<div class="america2">
<%= button_tag(type: 'submit', class: "btn") do %>
<span class="glyphicon glyphicon-plus"></span>
<% end %>
<%= link_to results_path, class: 'btn' do %>
<span class="glyphicon glyphicon-chevron-left"></span>
<% end %>
<%= link_to #result, method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn' do %>
<span class="glyphicon glyphicon-trash"></span>
<% end %>
</div>
</form>
</div>
<% end %>
For example User inputs:
:name = Ran
:metric = miles
Then for every month henceforth he would input his average miles ran for that month. How do I create a relationship between these two forms?
:result_value = 2.1
:result_date = January
:result_value = 1.8
:result_date = December
*Each name/metric has many result values/dates.
controllers
class QuantifiedsController < ApplicationController
before_action :set_quantified, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
def index
#averaged_quantifieds = current_user.quantifieds.averaged
#instance_quantifieds = current_user.quantifieds.instance
#results = Result.all.order("result_date")
end
def show
end
def new
#quantified = current_user.quantifieds.build
end
def edit
end
def create
#quantified = current_user.quantifieds.build(quantified_params)
if #quantified.save
redirect_to quantifieds_url, notice: 'Goal was successfully created'
else
render action: 'new'
end
end
def update
if #quantified.update(quantified_params)
redirect_to quantifieds_url, notice: 'Goal was successfully updated'
else
render action: 'edit'
end
end
def destroy
#quantified.destroy
redirect_to quantifieds_url
end
private
def set_quantified
#quantified = Quantified.find(params[:id])
end
def correct_user
#quantified = current_user.quantifieds.find_by(id: params[:id])
redirect_to quantifieds_path, notice: "Not authorized to edit this goal" if #quantified.nil?
end
def quantified_params
params.require(:quantified).permit(:categories, :name, :metric, :result, :date)
end
end
class ResultsController < ApplicationController
before_action :set_result, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
def index
#results = Result.all.order("result_date")
end
def show
end
def new
#result = current_user.results.build
end
def edit
end
def create
#result = current_user.results.build(result_params)
if #result.save
redirect_to #result, notice: 'Goal was successfully created'
else
render action: 'new'
end
end
def update
if #result.update(result_params)
redirect_to #result, notice: 'Goal was successfully updated'
else
render action: 'edit'
end
end
def destroy
#result.destroy
redirect_to results_url
end
private
def set_result
#result = Result.find(params[:id])
end
def correct_user
#result = current_user.results.find_by(id: params[:id])
redirect_to results_path, notice: "Not authorized to edit this result" if #result.nil?
end
def result_params
params.require(:result).permit(:result_value, :result_date)
end
end
The index would turn something out like this where each name (metric)'s would have multiple results and dates:
I tried implementing these instructions but I keep getting different errors with different variations: http://archive.railsforum.com/viewtopic.php?id=717
I also tried this tutorial: http://railscasts.com/episodes/197-nested-model-form-part-2. But it's a bit outdated so I get a bunch of errors.
Thanks in advance for any help you could give me!
what you are trying to do is NestedAttributes you can read more about it http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html
Examples:
# creates avatar_attributes=
accepts_nested_attributes_for :avatar, reject_if: proc { |attributes| attributes['name'].blank? }
# creates avatar_attributes=
accepts_nested_attributes_for :avatar, reject_if: :all_blank
# creates avatar_attributes= and posts_attributes=
accepts_nested_attributes_for :avatar, :posts, allow_destroy: true
this is the class definition
# File activerecord/lib/active_record/nested_attributes.rb, line 301
def accepts_nested_attributes_for(*attr_names)
options = { :allow_destroy => false, :update_only => false }
options.update(attr_names.extract_options!)
options.assert_valid_keys(:allow_destroy, :reject_if, :limit, :update_only)
options[:reject_if] = REJECT_ALL_BLANK_PROC if options[:reject_if] == :all_blank
attr_names.each do |association_name|
if reflection = _reflect_on_association(association_name)
reflection.autosave = true
add_autosave_association_callbacks(reflection)
nested_attributes_options = self.nested_attributes_options.dup
nested_attributes_options[association_name.to_sym] = options
self.nested_attributes_options = nested_attributes_options
type = (reflection.collection? ? :collection : :one_to_one)
generate_association_writer(association_name, type)
else
raise ArgumentError, "No association found for name `#{association_name}'. Has it been defined yet?"
end
end
end
Also if you need more there is a really cool video from rails cast that explains it http://railscasts.com/episodes/196-nested-model-form-part-1

Button doesn't update in Ajax on Users Index page - Rails Tutorial 4

TLDR: Trying to add a follow/unfollow button to the Users#Index action but when clicking on the button nothing happens.
I have followed Michael Hartl's Rails Tutorial app and now that it's complete I want to add extra functionality for the Follow/Unfollow button. Currently, you can only follow/unfollow a user after visiting their profile page thru the Users Show action. I've attempted to expand this functionality to the Index page of the Users controller so that instead of having to visit each user's profile page in order to follow/unfollow them, a follow button will also appear next to their name in the Index view.
The code that works initially for the follow/unfollow button on the Users Show action:
users_controller.rb
https://gist.github.com/anonymous/9602598
show.htlm.erb for users view
https://gist.github.com/anonymous/9602616
_follow_form.htlm.erb partial for users view
<% unless current_user?(#user) %>
<div id="follow_form">
<% if current_user.following?(#user) %>
<%= render 'unfollow' %>
<% else %>
<%= render 'follow' %>
<% end %>
</div>
<% end %>
_follow.html.erb partial for users view
<%= form_for(current_user.relationships.build(followed_id: #user.id),
remote: true) do |f| %>
<div><%= f.hidden_field :followed_id %></div>
<%= f.submit "Follow", class: "btn btn-large btn-primary" %>
<% end %>
_unfollow.html.erb partial for users view
<%= form_for(current_user.relationships.find_by(followed_id: #user.id),
html: { method: :delete },
remote: true) do |f| %>
<%= f.submit "Unfollow", class: "btn btn-large" %>
<% end %>
create.js.erb inside of my relationships view
$("#follow_form").html("<%= escape_javascript(render('users/unfollow')) %>")
$("#followers").html('<%= #user.followers.count %>')
destroy.js.erb inside of my relationships view
$("#follow_form").html("<%= escape_javascript(render('users/follow')) %>")
$("#followers").html('<%= #user.followers.count %>')
index.html.erb inside of the users view
<%= render #users %>
_user.html.erb partial inside of users view
<li>
<%= gravatar_for user, size: 52 %>
<%= link_to user.name, user %>
<% if current_user.admin? && !current_user?(user) %>
| <%= link_to "delete", user, method: :delete,
data: { confirm: "You sure?" } %>
<% end %>
I've tried a few different approaches that so far have been fruitless
First I tried simply rendering the follow_form partial inside of the _user partial just like it's done for the User Show view
_user.html.erb partial inside of users view
<%= render 'follow_form' if signed_in? %>
this resulted in the following error: NoMethodError in Users#index "undefined method `id' for nil:NilClass" and it hilights the following line of code inside of the follow_form partial
<% if current_user.following?(#user) %>
After mucking around with the variables and the controller for a few hours I finally managed to get the buttons to show properly on the index page with the following code inside of the _user.html.erb partial
<li>
<%= gravatar_for user, size: 52 %>
<%= link_to user.name, user %>
<% if current_user.admin? && !current_user?(user) %>
| <%= link_to "delete", user, method: :delete,
data: { confirm: "You sure?" } %>
<% end %>
<% if current_user.following?(user) %>
<%= form_for(#current_user.relationships.find_by(followed_id: #users),
html: { method: :delete },
remote: true) do |f| %>
<%= f.submit "Unfollow", class: "btn btn-large" %>
<% end %>
<% else %>
<%= form_for(current_user.relationships.build(followed_id: #users),
remote: true) do |f| %>
<div><%= f.hidden_field :followed_id %></div>
<%= f.submit "Follow", class: "btn btn-large btn-primary" %>
<% end %>
<% end %>
</li>
This code however, only shows the correct follow/unfollow buttons for each user but when you click a button nothing happens. I also attempted to edit the JS files with the following code
create.js.erb
$("#follow_form").html("<%= escape_javascript(render('users/unfollow')) %>")
$("#user").html("<%= escape_javascript(render('users/unfollow')) %>")
$("#followers").html('<%= #user.followers.count %>')
destroy.js.erb
$("#follow_form").html("<%= escape_javascript(render('users/follow')) %>")
$("#user").html("<%= escape_javascript(render('users/follow')) %>")
$("#followers").html('<%= #user.followers.count %>')
This didn't have any effect.
The more I tinker with different parts of the code the more it's confusing me. Here is my relationships controller for good measure.
relationships_controller.rb
class RelationshipsController < ApplicationController
before_action :signed_in_user
def create
#user = User.find(params[:relationship][:followed_id])
current_user.follow!(#user)
respond_to do |format|
format.html { redirect_to #user }
format.js
end
end
def destroy
#user = Relationship.find(params[:id]).followed
current_user.unfollow!(#user)
respond_to do |format|
format.html { redirect_to #user }
format.js
end
end
end
I know it's alot but if anyone can help shed some light on my situation I would be very grateful. This is my first venture outside of tutorials and I figured it would be a good idea to try and add features to an already working project instead of start something from scratch.
Just in case anybody was on this question and was still looking for the correct Ajax code. This works with the existing controller and nothing else will have to be changed.
create.js.erb
var indexed_form = "follow_form_<%=#user.id%>"
if ( document.getElementById(indexed_form) ){
var jquery_indexed_form = "#" + indexed_form
$(jquery_indexed_form).html("<%= escape_javascript(render('users/unfollow')) %>");
}
else {
$("#follow_form").html("<%= escape_javascript(render('users/unfollow')) %>");
$("#followers").html('<%= #user.followers.count %>');
}
destory.js.erb
var indexed_form = "follow_form_<%=#user.id%>"
if ( document.getElementById(indexed_form) ){
var jquery_indexed_form = "#" + indexed_form
$(jquery_indexed_form).html("<%= escape_javascript(render('users/follow')) %>");
}
else {
$("#follow_form").html("<%= escape_javascript(render('users/follow')) %>");
$("#followers").html('<%= #user.followers.count %>');
}
_user.html.erb
<div class="col-md-2">
<% unless current_user?(user) %>
<% form_id = user.id.to_s %>
<div id="follow_form_<%= form_id %>">
<% if current_user.following?(user) %>
<%= form_for(current_user.active_relationships.find_by(followed_id: user.id),
html: { method: :delete },
remote: true) do |f| %>
<%= f.submit "Unfollow", class: "btn" %>
<% end %>
<% else %>
<%= form_for(current_user.active_relationships.build, remote: true) do |f| %>
<div><%= hidden_field_tag :followed_id, user.id %></div>
<%= f.submit "Follow", class: "btn btn-primary" %>
<% end %>
<% end %>
</div>
<% end %>
</div>
This is my first post. Yay! Hope it helps someone!
Use the following code in _user.html.erb partial:
<li>
<%= gravatar_for user, size: 52 %>
<%= link_to user.name, user %>
<% if current_user.admin? && !current_user?(user) %>
| <%= link_to "delete", user, method: :delete,
data: { confirm: "You sure?" } %>
<% end %>
<% if current_user.following?(user) %>
<%= form_for(current_user.relationships.find_by(followed_id: user.id),
html: { method: :delete },
remote: true) do |f| %>
<%= f.submit "Unfollow", class: "btn btn-large" %>
<% end %>
<% else %>
<%= form_for(current_user.relationships.build(followed_id: user.id),
remote: true) do |f| %>
<div><%= f.hidden_field :followed_id %></div>
<%= f.submit "Follow", class: "btn btn-large btn-primary" %>
<% end %>
<% end %>
</li>
I made couple of changes to the code in form_for method call in 2 places:
#current_user should be current_user.
Secondly, followed_id: #users should be followed_id: user.id

Categories

Resources