Spree - customize checkout process - after complete callback is not executing - spree

hi i have the following lines of code in my order_decorator.rb
Spree::Order.state_machine.before_transition :to => :delivery,
:do => :valid_geolocation?
Spree::Order.state_machine.after_transition :to => :complete,
:do => :notify_shops_new_order
valid_geolocation? gets called before transitioning to :delivery but notify_shops_new_order is not called after the complete state.
I have no clue why. I'm using paypal to do the checkout. I don't know if this could be related.

If you're using the spree_paypal_express gem, it doesn't use a natural state machine transition to the complete state, and therefore the after complete callback won't be called. What's worked for me in the past is to chain your call to the finalize! method:
# in order_decorator.rb
def finalize_with_notify_shops!
finalize_without_notify_shops!
notify_shops_new_order
end
alias_method_chain :finalize!, :notify_shops

Related

ruby rails test case failing but real app works

So here's a strange problem: When I start my local rails app and browse to http://localhost:3000/static_pages/help I can see the page I created there.
However, the test case that I wrote says otherwise.
static_pages_controller_test.rb
require 'test_helper'
class StaticPagesControllerTest < ActionController::TestCase
test "should get home" do
get :home
assert_response :success
end
test "should get help" do
puts static_pages_help_url
puts static_pages_help_path
get static_pages_help_url
assert_response :success
end
end
It fails with this error, Output of $bin/rake test:
Running:
..http://test.host/static_pages/help
/static_pages/help
E
Finished in 0.466745s, 8.5700 runs/s, 4.2850 assertions/s.
1) Error.
StaticPagesControllerTest#test_should_get_help:
ActionController::UrlGenerationError: No route matches {:action=>"http://test.host/static_pages/help", :controller=>"static_pages"}
test/controllers/static_pages_controller_test.rb:12:in `block in <class:StaticPagesControllerTest>'
Here is routes.rb
Rails.application.routes.draw do
get 'static_pages/home'
get "static_pages/help"
end
and here is the static_pages_controller.rb
class StaticPagesController < ApplicationController
def home
end
def help
end
end
and these two files
app/views/static_pages/home.html.erb
app/views/static_pages/help.html.erb
exist, as I can also see them when navigating to /static_pages/help in my browser. I've searched the web for hours, no clue.
$ rails --version
Rails 4.2.7.1
$ ruby --version
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
I must be missing something. Please help.
Since you're writing a controller spec, the parameter to a GET should be the action(controller method). But you're passing a URL. If you look at the error message, you can find that "http://test.host/static_pages/help" was passed into action. So, pass the name of the controller method as a symbol rather than the URL. Try
get :help
Note that help is the controller action.
However if you're interested in writing an integration test, you should inherit from ActionDispatch::IntegrationTest rather than ActionController::TestCase. So, your spec should look aomething like this.
class StaticPagesControllerTest < ActionDispatch::IntegrationTest
test "should get home" do
get static_pages_home_url
assert_response :success
end
test "should get help" do
get static_pages_help_url
assert_response :success
end
end
To learn more about integration and controller tests, see http://weblog.jamisbuck.org/2007/1/30/unit-vs-functional-vs-integration.html
Hope this helps!

Rails: aliasing the index action in the routes file

I have the following route set up. I need to make the index action automatically use the pubmed_search route below.
resources :users do
resources :publications do
collection do
get :pubmed_search
post :pubmed_list
end
end
end
I tried
resources :users do
resources :publications do
collection do
get 'publications', :action => :pubmed_search
get :pubmed_search
post :pubmed_list
end
end
end
Without luck I could just do a redirect in the index method of the controller but i am sure there is a Rails way to do this and I want to learn.
EDIT:
This works
get "/users/:user_id/publications" => "publications#pubmed_search", :as => "user_publications"
But isn't there a better way, using the RESTful resources?
This works
get "/users/:user_id/publications" => "publications#pubmed_search", :as => "user_publications"

Understanding Rails/Twitter On-click tweet on behalf of user

As preface, I've followed through some tutorials (i.e. Michael Hartl's) though I'm still fairly novice. Forgive any cloudy terminology.
I am trying to build a simple application in Rails 4 that does the following:
User logs into application (currently working with sign-in-with-twitter link and routing)
get "/auth/:provider/callback" => "sessions#create"
get "/signout" => "sessions#destroy", :as => :signout
Once <% if current_user %> is true, I have the view rendering a partial where there will be a list of simple buttons. When the user clicks a button I want the application to tweet on behalf of the current_user a preset string. Ideally, I'd do this all in ruby/rails.
These button functions are where I'm getting hung up. I've read a fistful of documents but there seem to be a lot of conflicting and old answers. Here's a quick list of the ones I think are closest, though not explicit about sending a tweet from a simple button/link in a view:
http://www.sitepoint.com/ruby-social-gems-twitter/
http://richonrails.com/articles/sending-a-tweet-to-twitter
Some call for controllers, a more robust oauth setup (which I have bundle installed and connected to the dev.twitter application, though not fleshed out beyond keys), and whatever else. It's got me turned around and I'm not yet good enough to synthesize all the information. Any help and direction would be great. Below are some other files in the app that might be helpful.
class SessionsController < ApplicationController
def create
auth = request.env["omniauth.auth"]
user = User.find_by_provider_and_uid(auth["provider"], auth["uid"]) || User.create_with_omniauth(auth)
session[:user_id] = user.id
redirect_to root_url, :notice => "Hi!"
end
def destroy
session[:user_id] = nil
redirect_to root_url, :notice => "Bye!"
end
end
And omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
provider :twitter, '_priv', '_priv'
end
Eep! I'm the author of the second link (RichOnRails). Did you take a look at the example app included with the tutorial? It does almost exactly what you want. If the tweets are hard coded you could approach it in a couple of different ways. If you take a look at the tweets controller, you'll see it takes a parameter called 'message'. Any message passed to that create method will tweet as the current user.
def create
current_user.tweet(twitter_params[:message])
end
The easiest (but not necessarily best) way to adapt this to fit your needs is to have a form for each tweet, and do a hidden field with the message you wish to tweet. The button becomes a submit for that particular form (you can add remote: true if you want to keep the page from refreshing, then use a bit of javascript to update the UI elements). Hope this helps.

View overriding using Deface

I am trying to insert a text on show page of Spree's product page.
My app/overrides/show_new.html.erb as follows:
Deface::Override.new(:virtual_path => "spree/products/show",
:insert_after => "[data-hook='product_show']",
:text => "<p>This is overriding......</p>",
:name => "show_new",
:disabled => false)
But, the view is not overridden. Am I missing something?
You must restart your app for the overrides to register first.
Otherwise, this seems correct (assuming your code is in app/overrides/something.rb)
Watch out if you are not on latest version, some views HTML are broken and it breaks deface.
https://github.com/spree/spree/issues/1056 (I ran into this issue last week)

No route matches with valid object

Having read this:
"No route matches" error?
I'm trying to figure out if there is a gem or way to monkey patch actionpack to get around this constraint.
Basically, I'm writing specs (they run fast), and I don't understand why actionpack throws this error when being applied to an object which isn't "saved".
For two reasons:
Why is it throwing a "No route matches" when it really should be throwing something more meaningful (e.g. object must be saved before a route can be constructed, or object ID is nil). The exception seems a little obscure.
I shouldn't have to save the object at all if all I am trying to do is generate a url for that object, given the ID is populated using a factory or something similar.
This constraint makes it a pain to write fast tests, unless I'm missing something...
True, the error message is a bit obscure. Regarding your second point, you don't need to save an object to generate a URL, the helper will work just as well with a literal value.
building_path(1) # GET /buildings/1 => BuildingsController#show, params={:id=>"1"}
So in the example the object can be replaced with any value:
get :show, :id => "1"
For example, if you use rails generate scaffold Article, RSpec will build a spec like this:
def mock_article(stubs={})
(#mock_article ||= mock_model(Article).as_null_object).tap do |article|
article.stub(stubs) unless stubs.empty?
end
end
describe "GET show" do
it "assigns the requested article as #article" do
Article.stub(:find).with("37") { mock_article }
get :show, :id => "37"
assigns(:article).should be(mock_article)
end
end
which does not hit the database.