The action 'show' could not be found for CommentsController - javascript

I'm all new, and I'm trying to create a blog using Ruby on rails on windows 8.1.
I've made most of it, but it gives me "The action 'show' could not be found for CommentsController".
I've read several places it might be a lack of a javascript, but I have no idea where to post it.
<h1><%= #post.title %> </h1>
<%= #post.text %>
<h2>Comments</h2>
<% #post.comments.each do |comment| %>
<p><%= comment.text %></p>
<p><%= time_ago_in_words comment.created_at %></p>
<p><%= link_to "Delete comment", [#post, comment], :method => :delete, :confirm => "Are you sure?" %></p>
<% end %>
<%= form_for [#post, #post.comments.build] do |f| %>
<p><%= f.text_area :text, :size => '40x10' %></p>
<p><%= f.submit "Post comment" %></p>
<% end %>
<p>
<%= link_to "Tilbage", posts_path %>
|
<%= link_to "Rediger", edit_post_path(#post) %>
|
<%= link_to "Slet", #post, :method => :delete, :confirm => "Er du sikker?" %>
</p>
This is my code in question. Any help is appreciated :)
Edit: If there is other parts you need, just let me know
Edit:
CommentController
class CommentsController < ApplicationController
def create
params.permit!
#post = Post.find(params[:post_id])
#comment = #post.comments.build(params[:comment])
#comment.save
redirect_to #post
end
def destroy
#comment = Comment.find(params[:id])
#comment.destroy
redirect_to #comment.post
end
end
Routes
Rails.application.routes.draw do
get 'comments/create'
get 'comments/destroy'
resources :posts do
resources :comments
end

Related

Counter span on my like button not updating with ajax

I have followed the answers suggested on other questions on SO (this question and this question ), but for some reason I can't get my like button counter to work properly with ajax. My counter changes only after a refresh, any help is appreciated thanks!
meals_controller.rb
def upvote
#meal.upvote_from current_user
if request.xhr?
render json: { count: #meal.get_upvotes.size, id: params[:id] }
else
redirect_to meals_path
end
end
def unlike
#meal.unliked_by current_user
redirect_to meals_path
end
routes.rb
Rails.application.routes.draw do
devise_for :users
root 'home#index'
resources :meals do
member do
put "like" => "meals#upvote"
put "unlike" => "meals#unlike"
end
end
#upvote.coffee
$(document).on 'ajax:success', 'a.vote', (status,data,xhr)->
$(".votes-count[data-id=#{data.id}]").text data.count
return
#index.html.erb
<p id="notice"><%= notice %></p>
<h1>Listing Meals</h1>
<% #meals.each do |meal| %>
<%= meal.title %>
<br>
<%= meal.descriptionttext %>
<%= link_to like_meal_path(meal), class: "vote", method: :put, remote: true do %>
<button>
<span class="votes-count" data-id="<% meal.id %>"><%= meal.get_likes.size %></span>
</button>
<% end %>
<%= link_to unlike_meal_path(meal), method: :put do %>
<button type="button">
<span><%= meal.get_upvotes.size%></span>
</button>
<% end %>
<br>
<% end %>
<br>

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

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

In my comment app when i refresh the page comments disappears

My comment app works ,but the only problem is whenever i refresh the page the comments disappear.In the log it shows the body is inserted in the comments table(it is saved).What am i doing wrong here?Any help will be appreciated.Thank you in advance.
View#show
<div id="comments"></div>
<%= form_for :comment,:remote => true,:url=> {:controller=>"comments",:action=>"create"},:html => { :id => 'new-comment'} do |f| %>
<%= f.text_area(:body) %>
<div class="errors"></div>
<%= f.submit "post" %>
<% end %>
Comment controller
class CommentsController < ApplicationController
respond_to :js
def create
#deal=Deal.find(1)
#comment =#deal.comments.build(params[:comment])
#comment.save
respond_with( #comment, :layout => !request.xhr? )
end
def show
#comment=Comment.all
#deal=Deal.find(1)
#comment=#deal.comments
end
end
create.js.erb
$('#comments').append("escape_javascript(#comment.body)");
I don't see where your comments are being display in your show template.
How about something like this?
<div id="comments">
<% #comments do |comment| %>
<%= comment.body %>
<% end %>
</div>
<%= form_for :comment,:remote => true,:url=> {:controller=>"comments",:action=>"create"},:html => { :id => 'new-comment'} do |f| %>
<%= f.text_area(:body) %>
<div class="errors"></div>
<%= f.submit "post" %>
<% end %>
Note, you need to set #comments in the controller or use another method of getting comments, e.g. #view = View.find(params[:id]) and <%= #view.comments.each do |comment| %>...
I guess the comment has a belongs_to relationship with the post that is not assigned.
In your form you should add
<%= f.hidden_field :post_id, #post.id %>
If you want to play by the book, post_id should be attr_protected and instead assign it manually in the comments controller
#comment = Comment.new(params[:comment])
#comment.post_id = params[:comment][:post_id]
#comment.save

Dynamically add & remove new but the same fields of a form any amount times

I have a form that has no nested models.
class UserProductsController
def new
#user_product = current_user.user_products.build
end
end
With jquery/javascript i want to add and remove new #user_product fields on the same form. This how it would look normally:
<%= form_for(#user_product) do |f| %>
<%= f.error_messages %>
<%= f.text_field :product %>
<%= f.text_field :address %>
<%= f.text_field :price %>
<%= f.submit %>
<% end %>
And I'm trying to achieve:
<%= form_for(#user_product) do |f| %>
<%= f.error_messages %>
<%= f.text_field :product_name %>
<%= f.text_field :address %>
<%= f.text_field :price %>
---New ID(New generated ID, could be any new number in the database)
<%= f.text_field :product_name %>
<%= f.text_field :address %>
<%= f.text_field :price %>
<%= Remove this Product %> # ajax style, this link removes this product entirely
----ID 3----
<%= f.text_field :product_name %>
<%= f.text_field :address %>
<%= f.text_field :price %>
<%= Remove this Product %>
-----Add link------
<%= Add Another Field %> # ajax style adding
<%= f.submit %>
<% end %>
Notice the new IDs that aren't preset and the one submit button so this way more then one Product can be created at a time by a User. How do i achieve the above?
Thank you.
Answer:
Using the User.rb model you can do what James said. Here is my form that works.
<%= form_for(current_user, :url => user_products_path) do |f| %>
<%= f.error_messages %>
<%= f.fields_for :user_products do |builder| %>
<%= render "user_product_fields", :f => builder %>
<% end %>
<%= link_to_add_fields "Add a UserProduct", f, :user_products %>
<%= f.submit "Create" %>
<% end %>
_user_product_fields.html.erb
<div class="fields">
<%= f.label :product, "Product" %>
<%= f.text_field :product %>
<%= f.label :address, "Address" %>
<%= f.text_field :address %>
<%= f.label :price %>
<%= f.text_field :price %>
<%= link_to_remove_fields "remove", f %>
</div>
As others have suggested (somewhat unhelpfully), use nested forms.
You need the form to be based on the current_user object with fields_for declaration for :user_products. You will need to set the url for the form to post back to the user_product controller not the user controller using url_for and you will need to adjust the user_product controllers update and create actions to make use of params[:user] instead of params[:user_product]
If you have your accepts_nested_attributes configured properly all should be good.
BTW if you follow those railscasts you will find that the javascript to add new will not work for Rails 3.x
You should use something like this for your view helpers
module ApplicationHelper
def link_to_remove_fields(name, f)
f.hidden_field(:_destroy) + link_to_function(name, "remove_fields(this)")
end
def link_to_add_fields(name, f, association)
new_object = f.object.class.reflect_on_association(association).klass.new
fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
render(association.to_s.singularize + "_fields", :f => builder)
end
link_to_function(name, "add_fields(this, '#{association}', '#{escape_javascript(fields)}')")
end
end
and something like this for your javascript in your application.js file
// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults
function remove_fields(link) {
$(link).previous("input[type=hidden]").value = "1";
$(link).up(".fields").hide();
}
function add_fields(link, association, content) {
var new_id = new Date().getTime();
var regexp = new RegExp("new_" + association, "g")
$(link).up().insert({
after: content.replace(regexp, new_id)
});
}
and obviously your form_for need to be refactored to something like this
<%= form_for(current_user, :url => user_product_path) do |f| %>
<!-- add your f.fields_for :user_products here, probably in a rendered partial -->
<%end%>
That should be enough with the rails casts to get you going
Checkout this:
http://railscasts.com/episodes/196-nested-model-form-part-1
http://railscasts.com/episodes/197-nested-model-form-part-2
You can use cocoon for this.

Categories

Resources