I'm trying to enable the user to edit the number of credit cards they have on file, they'll have the option to delete it.
It would be simple enough in traditional rails, but I'm new to spree and not sure how things work during checkout.
In views:
- #cards.each do |card|
= card.last_digits
= "#{card.month+'/'+card.year}"
= button_to "delete", {:controller => :credit_cards,
:action => 'destroy', :id => card.id, :method => :delete, :confirm => 'are you sure?'}
Controller:
module Spree
class CreditCardsController < Spree::BaseController
def destroy
#credit_card = Spree::CreditCard.find(params["id"])
#credit_card.destroy
.
.
.
Right now the button generated seems to work, when I press on it from checkout/payment it goes to checkout/update/payment and then stops at checkout/confirm but the credit card in not deleted.
Any help would be greatly appreciated!
what's the filename of your controller? are you intending to override the spree class CreditCardsController? if so:
Spree::CreditCardsController.class_eval do
def destroy
#credit_card = Spree::CreditCard.find(params["id"])
#credit_card.destroy
...
end
end
...but i think that controller method is in the Api namespace. what about calling the drop_payment_source method? https://github.com/spree/spree/blob/45cec5215763da26e0089415f4c49afffd683bd9/core/app/models/concerns/spree/user_payment_source.rb#L13
...if you want define your own CreditCardsController class then you should setup something in your routes.rb file so you can use a route helper method in the button_to method (instead of calling out the controller & method name). also, you need to redirect or something in your destroy method. maybe to checkout_path? run rake routes to find more.
Related
I'm creating rails product controller to hide the product without deleting user grid panel using Boolean values, but I'm trying so many times, it's not working. I'm just show my code..please help where i'm missing...
I'm using ruby 2.4.1, rails 5.3.2 please help me.
rails route is,
post 'products/hide', to: 'products#hide'
products controller function is,
def hide
#product = Product.find(params[:id])
#product.hidden = true
flash[:notice] = 'you have successfully hide your product'
redirect_to suppliers_index_path
end
view form is,
<%= link_to 'delete', product, method: :hide, data: { confirm:
"Are you sure hide this #{product.Product_name} ?" } %>
products table migration are
class AddHiddenToProducts < ActiveRecord::Migration[5.2]
def change
add_column :products, :hidden, :boolean, :default => false
end
end
please help to resolve this issue.
There's a handful of things wrong with your code.
The most important issue is that you aren't saving your changes.
Your controller code which reads #product.hidden = true only assigns the value to the ruby object in memory. It does not save that change to the database. I believe this is the code you want in your controller action.
def hide
#product = Product.find(params[:id])
#product.update_attribute(:hidden, true)
flash[:notice] = 'you have successfully hide your product'
redirect_to suppliers_index_path
end
Your link_to is attempting to use a non-standard HTTP method ("hide"). I can tell that you're interpreting this as the controller method you want to hit, but that's not what method: means here. The method: parameter in link_to allows you to specify which HTTP method you want to send along with the request. HTTP methods are a standard that function as "verbs" that tell the server what you want to do to the resource you're requesting. Since you're only updating one attribute on the object, the Mozilla Foundation would instruct you to use the PATCH method for your request here.
NOTE: We'll be updating the route to match this in the next point.
COMMENT: Whoever named the product's "name" column products.Product_name needs to have a code review meeting with someone. But anyway...
<%= link_to 'delete', product, method: :patch, data: { confirm:
"Are you sure hide this #{product.Product_name} ?" } %>
Your routes need to be mapped to respond to a PATCH method request. You could use the format you use in your example, but most of the time you want to use "resourceful" routes.
resources :products do
member do
patch :hide
end
end
I will add that you don't have to use the PATCH method at all. You could also use put :hide + method: :put or post :hide + method: :post. They just need to match.
The key method passed to link_to call doesn't define controller method, but HTTP method, so it should be :post actually. You specify controller method by setting correct path/http method. You can achieve your goal by:
<%= link_to 'delete', { controller: products, action: :hide, id: product }, method: :post, data: { confirm: "Your confirmation" } %>
But I would go a little bit further and provide correct named route, assuming you have resources :products somewhere in your routes:
resources :products do
member do
post :hide
end
end
and in your view:
<%= link_to 'delete', [:hide, product], method: :post, data: { confirm: "Confirmation text" } %>
I this view is currently in the views/projects/show.html.erb file however I want it to use the website controller for deleting this file:
<%= link_to 'Delete', #website, :controller => 'website', :action => 'delete', method: :delete, data: {confirm: "Are you sure you want to delete this asset?"}%>
It returns the error 'Could not find action destroy in the ProjectsController'. Also i don't have #website defined in the projects controller so should I be using something else? Or am I still able to access it because it is defined in the websites controller.
#controllers/websites_controller.rb
class WebsitesController < ApplicationController
def new
#project = Project.find(params[:project_id])
#website = #project.assets.build(:type => 'Website', :project_id => Project.find(params[:project_id]), :asset_number => #project.assets.size + 1)
end
def create
#website = current_user.assets.build(website_params)
#website.update_attributes(:project_id => #project)
if #website.save
flash[:notice] = "Asset successfully added."
redirect_to(:controller => 'projects', :action => 'show', :id => #website.project_id)
else
render(:action => 'new')
end
end
def delete
#website = Asset.find(params[:id])
end
def destroy
asset = Asset.find(params[:id]).destroy
flash[:notice] = "The asset '#{asset.title}' has been destroyed Successfully."
redirect_to(:controller => 'projects', :action => 'index')
end
private
def website_params
params.require(:website).permit(:id, :project_id, :asset_number, :title, :type, :url, :page_rank, :rev_company ,:social_pages)
end
end
If you are using this link on the show page for projects then #website will not be available unless it is defined in the projects controller.
That said, if there is some relationship between the project and the website, you could use that as opposed to defining #website in your projects controller.
Also, as far as your link_to is concerned, I do not believe that you can specify controller and action in the link_to like that. Instead, you should use the path to #website. Which should make your link_to look something more like this:
<%= link_to "Delete", website_path(#website), method: :delete, data: {confirm: "Are you sure you want to delete this asset?" %>
However, the model that your websites_controller appears to handle is actually an Asset. Without seeing your routes it is hard to guess how you have set them up, but assuming that you do something like
map.resources :assets, :controller => 'websites'
in your routes. Then in your link_to instead of using website_path(#website) you would likely use asset_path(#website).
Generally speaking, it is rarely a good idea to defy rails convention by naming things inconsistently from your model in ruby. If your Asset model uses single table inheritance or you are implying something like single table inheritance and are using controllers to separate responsibilities, then this may perhaps be an exception, but you will still need to be careful to ensure you are mapping to the correct place in your routes.
You may want to read up on the rails guide for routing, as it is a very good resource and explains pretty well how destroy gets mapped, which in turn explains why the link_to for it looks the way that it does.
#website available in the show action is the the one defined in the projects controller because it is he one rendering the current html page.
Therefore the one you wish to delete is not available at the moment.
I'm setting up a follow system with the Rails Gem acts_as_follower and I've run into a problem I'm not sure how to fix.
When I go to follow for example a user with the username of 'testuser1' I get this error:
Couldn't find Member with id=testuser1
app/controllers/follows_controller.rb:6:in `create'
Parameters:
{"_method"=>"post",
"authenticity_token"=>"FnqLCCQYcFGMerOB56/G6dlPvzpPhPDFbxCXaiDBOUU=",
"member_id"=>"testuser1"}
Here's my Controller:
class FollowsController < ApplicationController
before_filter :authenticate_member!
def create
#member = Member.find(params[:member_id])
current_member.follow(#member)
end
def destroy
#member = Member.find(params[:member_id])
current_member.stop_following(#member)
end
end
The form to create the follow:
<%= link_to("Follow", member_follows_path(member.to_param), :method => :post, :class => "btn") %>
<%= link_to("Following", member_follow_path(member.to_param, current_member.get_follow(member).id), :method => :delete, :class => "btn btn-follow") %>
And this is how I've defined my to_param since that's how you get to a member/user's page:
def to_param
user_name
end
Anyone out there know how I can go about fixing this? Thanks.
Remove the to_param. When you're using the URL helpers, such as your member_follows_path, you need to pass the ID, or from the ERB's perspective, the object itself (it'll resolve to the ID when the ERB renders)
Alternatively, in your rails controller, change the find to something like find_by_user_name, or whatever the field is supposed to be, and then that line should work. Beware that this will be slower, especially if you have a large database without proper indexing / partitioning.
I have something like this in view:
<% if actions.include? "delete" %>
<%= link_to 'UsuĊ', asset_path(asset), :method => :delete, :data => { :confirm => "Want to delete it?" }, :role => "link" %>
<% end %>
and this in assetcontroller:
def destroy
#asset = current_user.assets.find(params[:id])
#asset.destroy
redirect_to assets_path
end
the question is, why it "use" destroy method when action in view is "delete" ?
delete is method of HTTP protocol. destroy is the action of your controller.
Route with delete HTTP method leads to destroy action.
To edit this routes and make delete HTTP method lead to delete action (for example), you should edit config/routes.rb file.
This is because in your routes.rb file you have defined the model as a resource (or a generator like scaffold did). This means that the default CRUD routes are generated. If you want to do it another way, use your own routes instead of generating them.
http://guides.rubyonrails.org/routing.html#crud-verbs-and-actions
I am trying to convert my Rails 2 app to Rails 3, but I can't delete any resources using my old Rails 2 code. To be precise I am trying to delete a resource, using this link:
<%= link_to image_tag("misc/delete.png"), #book, :confirm => 'Are you sure?', :method => :delete %>
And yet it doesn't work at all! It just behaves as if the :confirm option and :method option haven't been set at all, i.e. redirects me to the url of the #book object without even showing an alert box.
The generated HTML in Rails 3 is:
<img alt="Delete" src="/images/misc/delete.png?1205252772">
The generated HTML in Rails 2 was:
<img alt="Delete" src="/images/misc/delete.png?1279402305">
It's an obvious difference, but I've got no idea how I should handle this problem.
My controller looks like so:
class BooksController < ApplicationController
before_filter :require_admin, :only => ['new', 'create', 'edit', 'update', 'destroy']
# ....
def destroy
puts "-------------- DESTROYING BOOK --------------"
#book = Book.find(params[:id])
#book.destroy
flash[:notice] = "Successfully destroyed book."
session[:restore] = request.referer
redirect_to back(edit_author_url(#book.author))
end
end
And the string "destroying book" doesn't show on the console, so I think there surely must be something wrong.
Has something in the restful handling been changed in Rails 3 that I should get to know of?
Thanks, guys!
You need add the rails javascript library.
To jQuery : http://github.com/rails/jquery-ujs
To Prototype : http://github.com/rails/prototype-ujs