I've seen numerous posts about this issue but none of them have helped.
As a lot of people, I'm trying to have a delete link to delete heore order_items.
When I had Turbolinks working I had no issue with those links, except that because of Turbolinks my pages couldn't load properly. I removed it and now I'm trying to fix my links.
Here's my template:
_cart_row_html.erb
<%= simple_form_for order_item, authenticity_token: true, remote: true do |f| %>
<td><%= product.reference %></td>
<td><%= product.name %></td>
<td><%= f.number_field :quantity, value: order_item.quantity.to_i, class: "form-control", min: 1 %></td>
<td><%= f.button :submit, "Mettre à jour la quantité", class: "btn btn-primary" %></td>
<td><%= link_to '<i class="fas fa-trash"></i>'.html_safe, 'data-method' => :delete %> </td>
<td><%= number_to_currency order_item.total_price, locale: :fr %></td>
<% end %>
My routes.rb:
Rails.application.routes.draw do
root to: "home#index"
devise_for :users, controllers: { registrations: "registrations", sessions: "sessions" }
resource :cart, only: [:show]
resources :order_items, only: [:create, :update, :destroy]
resources :categories
resources :products
get 'orders/validate_cart', as: 'validate_cart'
get 'orders/validate_coordinates', as: 'validate_coordinates'
#get 'order_items/create'
#get 'order_items/update'
#get 'order_items/destroy'
get 'carts/show'
get '/articles/:category', to: 'articles#index', as: 'list_product_by_category'
get '/articles/:categories/:id', to: 'articles#show', as: 'product_detail'
get '/users', to: 'users#index', as: 'users_list'
get 'dashboard' => 'dashboard#index'
end
My application.js:
//= require jquery3
//= require rails-ujs
//= require activestorage
//= require popper
//= require bootstrap-sprockets
//= require akame.bundle
And finally my oder_items_controller.rb
class OrderItemsController < ApplicationController
def create
#order = current_order
#order_item = #order.order_items.new(order_item_params)
#order.save
session[:order_id] = #order.id
redirect_to request.referrer
end
def update
#order = current_order
#order_item = #order.order_items.find(params[:id])
#order_item.update_attributes(order_item_params)
#order_items = #order.order_items
#order.save
redirect_to request.referrer, notice: "La quantité a bien été mise à jour"
end
def destroy
#order = current_order
#order_item = #order.order_items.find(params[:id])
#order_item.destroy
#order_items = #order.order_items
if #order_items.length <=0
reset_session
redirect_to carts_show_path
else
redirect_to carts_show_path, notice: "Le produit a bien été supprimé"
end
end
private
def order_item_params
params.require(:order_item).permit(:quantity, :product_id)
end
end
So far I've tried all of those solutions:
- Replace method by data-method
- Use <%= javascript_include_tag :application %> into my application.html.erb file
- Check if
//= require jquery3
//= require rails-u
are in my application.js
with the help of those posts for e.g.: I can't delete a post in Rails
Can't Edit Or Delete Javascript in Rails
EDIT: when I use this path <td><%= link_to '<i class="fas fa-trash"></i>'.html_safe, order_item_path(#order_item), 'data-method' => :delete %> </td> I have this error : "No route matches {:action=>"update", :controller=>"order_items", :id=>nil}, missing required keys: [:id]"
What am I missing ? It's driving me nuts for days now ...
In your
<%= link_to "Ajouter au panier", order_item_path(#order_item), class: "btn btn-primary" %>
Your path should look like this order_item_path(#order_item), method: :delete so you point to the destroy action. It also looks like you are using #order_item and it's nil, in your _cart_row.html.haml you have a local variable order_item so you probably should use that.
Hope it helps
I've changed my code to <%= link_to '<i class="fas fa-trash"></i>'.html_safe, order_item_path(order_item), 'data-method' => :delete %> and it DOES work even if I'm pretty sure I tested that before. Anyway I'm glad it works. I'm upvoting your answer. Thanks !
Related
I am following a tutorial from devfactor.com. It's called "Let's Build: Instagram with Rails." The author is using AJAX and js files in the tutorial. When added a file called "Index.js.erb", it showed many errors in my server.
Error:
ActionView::Template::Error (Missing partial posts/_posts, application/_posts wi
th {:locale=>[:en], :formats=>[:js, :html], :variants=>[], :handlers=>[:raw, :er
b, :html, :builder, :ruby, :coffee, :jbuilder]}. Searched in:
* "C:/Users/alouftur0/Rails/Photogram/app/views"
* "C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/kaminari-core-1.0.1/app/views"
* "C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/devise-4.3.0/app/views"
):
1: $('#posts').append("<%= escape_javascript(render 'posts')%>");
2: $('#paginator').html("<%= escape_javascript(link_to_next_page(#posts, 'LO
AD MORE', remote: true, id: 'load_more'))%>");
3: if (!$('#load_more').length) { $('#paginator').remove(); }
app/views/posts/index.js.erb:1:in `_app_views_posts_index_js_erb___1182481000_10
4067220'
Here are the files:
application.html.erb:
<!DOCTYPE html>
<html>
<head>
<title>Photogram</title>
<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>
<body>
<%= render 'posts/navbar' %>
<% flash.each do |key, value| %>
<div class="alert alert-<%= key %>"><%= value %></div>
<% end %>
<%= yield %>
</body>
</html>
Index.html.erb:
<% #posts.each do |post| %>
<%= render 'post', post: post %>
<% end %>
<div class="text-center" id="paginator">
<%= link_to_next_page #posts, 'LOAD MORE', remote: true, id: 'load_more' %>
</div>
index.js.erb:
$('#posts').append("<%= escape_javascript(render 'posts')%>");
$('#paginator').html("<%= escape_javascript(link_to_next_page(#posts, 'LOAD MORE', remote: true, id: 'load_more'))%>");
if (!$('#load_more').length) { $('#paginator').remove(); }
application.scss:
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's
* vendor/assets/stylesheets directory can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
* files in this directory. Styles in this file should be added after the last require_* statement.
* It is generally better to create a new file per style scope.
*
*= require_tree .
*= require_self
*/
#import "bootstrap-sprockets";
#import "bootstrap";
application.js:
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's
// vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file. JavaScript code in this file should be added after the last require_* statement.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require rails-ujs
//= require turbolinks
//= require_tree
That's it. The error message is above. if you have any questions, just comment it. Thank you!
Here is my Posts controller:
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
before_action :owned_post, only: [:edit, :update, :destroy]
def index
#posts = Post.all.order('created_at DESC').page params[:page]
respond_to do |format|
format.js
format.html
end
end
def show
end
def new
#post = current_user.posts.build
end
def create
#post = current_user.posts.build(post_params)
if #post.save
redirect_to posts_path
flash[:success] = "Post Created!"
else
flash.now[:success] = "Your new post couldn't be created! Please check the form."
render :new
end
end
def edit
end
def update
if #post.update(post_params)
redirect_to posts_path
else
flash.now[:alert] = "Update failed. Please check the form."
render :edit
end
end
def destroy
#post.destroy
redirect_to root_path
flash[:success] = "Destroyed ;)"
end
private
def owned_post
unless current_user == #post.user
flash[:success]= "That post doesn't belong to you :("
redirect_to root_path
end
end
def post_params
params.require(:post).permit(:image, :caption)
end
def set_post
#post = Post.find(params[:id])
end
end
You need to render partial such as
$('#posts').append('<%= escape_javascript(render #posts) %>');
Your index.html.erb file is missing a #posts selector for the $('#posts').append('<%= escape_javascript(render #posts) %>') command in index.js.erb to append to.
<div id="posts">
<%= render 'posts' %>
</div>
<div class="text-center" id="paginator">
<%= link_to_next_page #posts, 'LOAD MORE', remote: true, id: 'load_more' %>
</div>
As the error suggests, you also need a posts/_post.html.erb partial, which is what the JS partial is trying to render.
I'm trying to delete a "budget"(in portuguese, "orçamento") via ajax request, and that budgets have a relationship belongs to cadastre and cadastre has many budgets. My components are as follows:
orcamentos_controller.rb
.
.
.
def destroy
#cadastro = Cadastro.find(params[:cadastro_id])
#orcamento = #cadastro.orcamentos.find(params[:orcamento_id])
#orcamento.destroy
respond_to do |format|
format.js { head :ok }
end
end
def index
#cadastro = Cadastro.find(params[:cadastro_id])
#orcamentos = #cadastro.orcamentos.paginate(page: params[:page], per_page: 10)
end
.
.
.
index.html.erb
... <%= render "orcamentos_lista" %> ...
_orcamentos_lista.html.erb
<table class="table">
<% #orcamentos.each do |orcamento| %>
<tr id="remove_orcamento_<%= orcamento.id %>">
<td>
<%= link_to "Orçamento nº #{orcamento.id}, registrado em #{orcamento.created_at.strftime("%d/%m/%Y")}", "#", class: "list-group-item", type: 'button'%>
</td>
<td>
<%= link_to "Excluir", orcamento, method: :destroy, remote: true %>
</td>
</tr>
<% end %>
</table>
<% content_for :js do %>
<% #orcamentos.each do |orcamento| %>
$('#remove_orcamento_<%= orcamento.id %>').bind('ajax:success',
function(){
$('#orcamento_<%=orcamento.id%>').remove();
}
);
<% end %>
<% end %>
routes.rb
.
.
.
resources :cadastros do
resources :orcamentos
end
.
.
.
I get the error undefined method orcamento_path for #<#<Class:0x007f5f39757930>:0x007f5f39cf1eb8> this line <%= link_to "Excluir", orcamento, method: :destroy, remote: true %>
I am a beginner in both ruby as on rails, so forgive me any ugliness in code.
run
rake routes
Then whatever path you want that link to have in it find it in the table of routes and use the 'prefix' for it with "_path" at the end. So if the resource you want is on that table and has a prefix of foo_bar then your link_to should have foo_bar_path used in your view.
so change this line
<%= link_to "Excluir", orcamento, method: :destroy, remote: true %>
to this
<%= link_to "Excluir", foo_bar_path, method: :destroy, remote: true %>
The problem you have is that you're calling orcamento as the link, when you've nested it within cadastros:
#config/routes.rb
resources :cadastros do
resources :orcamentos # -> url.com/cadastros/:catastros_id/orcamentos/:id
end
This means if you want to call the path helper for an orcamentos, you have to use the nested resource:
cadastros_orcamentos_path(#cadastros, orcamento)
If you're using link_to, you should be able to pass an array of the nested objects as you require:
link_to "Delete", [#cadastros, orcamento], method: :delete
I want to add the Favorite function in my rails app. I added a partial favorite to show.html.erb, it will show the favorite link or unfavorite link, if I favorite a article, doesn't need to refresh whole page:
#app/views/articles/show.html.erb
<div class="panel-body"><p><%= markdown(#article.content) %></p></div>
<div class="panel-footer" id="favorite">
<div><%= render 'favorite_link' %></div>
...
_favorite_link.html.erb:
<% if not Favorite.where(user_id: current_user.id, article_id: #article.id).first %>
<%= link_to 'favorite', favorite_article_path(#article), {id: #article.id, method: :post}, remote: true %>
<% else %>
<%= link_to 'unfavorite', unfavorite_article_path(#article), method: :delete, remote: true %>
<% end %>
favorite.js.erb:
$("#favorite").html("<%= escape_javascript render partial: 'favorite_link' %>");
ArticlesController:
def favorite
#article = Article.find(params[:id])
#article.favorites.create(user_id: current_user.id)
render 'favorite'
end
def unfavorite
#article = Article.find(params[:id])
favorite = Favorite.where(user_id: current_user.id, article_id: #article.id).first
favorite.destroy
render 'favorite'
end
When I click favorite link, it doesn't work, error info as below:
ActionView::MissingTemplate (Missing template articles/favorite, application/favorite with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}. Searched in:
* "/Users/liuxingqi/Public/Sparta/my_blog/mongo_project/app/views"
* "/Users/liuxingqi/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/kaminari-0.16.3/app/views"
):
app/controllers/articles_controller.rb:90:in `favorite'
but unfavorite works well. Hope someone can help me! Thanks in advance!
It search for a view with HTML extention no JS and what you have is favorite.js.erb, to fix that the request to favorite should be ajax request and with format: js something like
articles_favorite_path(format: :js)
I found the root cause, because the wrong parameters order, the remote: true doesn't work.
<%= link_to 'favorite', favorite_article_path(#article), {id: #article.id, method: :post}, remote: true %>
should be:
<%= link_to 'favorite', favorite_article_path(#article), {id: #article.id, method: :post, remote: true} %>
I switched from a Sony computer to an Asus, downloaded the same programs as I had on the Sony and cloned my Rails 4.0.10 project from Bitbucket. Everything else behaves the same, but Paperclip has inexplicably stopped working, though the two development environments should be exactly the same. I used Paperclip to add an avatar to my User model, but now User.create fails when I attach an avatar. I tried uninstalling and reinstalling it, but that made no difference. Does anyone with Paperclip experience know what might have happened?
Gemfile:
gem "paperclip", :git => "git://github.com/thoughtbot/paperclip.git"
# ...
models/user.rb
class User < ActiveRecord::Base
has_attached_file :avatar, :styles => { :large => "500x500", :medium => "300x300>", :thumb => "50x50!" }, :default_url => "/images/:style/missing.png"
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
# ...
controllers/users.rb
class UsersController < ApplicationController
def create
# ...
if #user.save
render :action => "crop"
else
flash[:notice] = "Failed"
redirect_to new_user_path
end
end
private
def user_params
params.require(:user).permit(:name, :avatar)
end
views/users/new.html.erb
<%= form_for #user, :url => users_path, :html => { :multipart => true } do |f| %>
<%= f.text_field :name, :placeholder => "Name" %>
<br>
<%= f.label :display_picture %>
<%= f.file_field :avatar %>
<br>
<%= f.submit "Submit", class: "btn btn-primary" %>
<% end %>
views/users/crop.html.erb
<% content_for(:head) do %>
<%= stylesheet_link_tag "jquery.Jcrop" %>
<%= javascript_include_tag "jquery.Jcrop.min" %>
<script type="text/javascript" charset="utf-8">
ready = $(function() {
$("#cropbox").Jcrop();
});
</script>
<% end %>
$(document).ready(ready);
$(document).on('page:load', ready);
<%= image_tag #user.avatar.url(:large), :id => "cropbox" %>
Make sure imagemagick is installed on your machine. This isn't something 'bundle install' will cover.
Follow the instructions here
http://www.imagemagick.org/script/install-source.php
Or use homebrew or other package managers
I am developing a ruby on rails app which as vote up and vote down for products. The code is working the only problem I have is I need votes to be submitted via javascript and I have no idea how to begin this.
Heres my routes
resources :products do
member do
post :vote_up
post :vote_down
end
end
heres is my controller file
def vote_up
begin
#product = Product.find(params[:id])
current_user.vote_exclusively_for(#product)
#product.score = #product.plusminus
#product.save
render :nothing => true, :status => 200
rescue ActiveRecord::RecordInvalid
render :nothing =>true, :status => 404
end
end
def vote_down
begin
#product = Product.find(params[:id])
current_user.vote_exclusively_against(#product)
#product.score = #product.plusminus
#product.save
render :nothing => true, :status => 200
rescue ActiveRecord::RecordInvalid
render :nothing =>true, :status => 404
end
end
and here is my view file
<td><%= link_to "Vote up", vote_up_product_path(product), :method=>:post %></td>
<td><%= link_to "Vote down", vote_down_product_path(product), :method=>:post %></td>
javascript includes
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
<td><%= link_to "Vote up", vote_up_product_path(product), :method=>:post, :remote => :true %></td>
Then you can handle the response attaching an event handler to that link:
$(the_link_selector)
.on('ajax:success', function1) // Executed when server answers with successful code
.on('ajax:error', function2) // Executed when server answers with error code