ShopifySessionRepository.shop_storage is not configured - ruby-on-rails

I created a very basic Shopify App, and when I install it through the https://XXX.ngrok.io/login page I see the confirmation screen, however when clicking install, Rails throws the ShopifySessionRepository.shop_storage is not configured error. If I ignore the warning and navigate into the store, I see that the App was installed successfully regardless.
My controller:
class SpaV1Controller < ApplicationController
include ShopifyApp::EmbeddedApp # cookie-less architecture
include ShopifyApp::RequireKnownShop # cookie-less architecture
def index
#shop_origin = current_shopify_domain
#products = ShopifyAPI::Product.find(:all, params: { limit: 10 })
end
end
I am trying to use the new cookieless App Bridge, and I suppose this can be connected?

I was having this issue.
I had this in my shopify_app.rb initializer:
config.shop_session_repository = 'Shop'
Then I needed to run the following:
$ rails generate shopify_app:shop_model
$ rails db:migrate RAILS_ENV=development

Related

Rails "noticed gem" saying uninitialized constant

I am trying to get notifications to work in my app. I found "noticed gem" from this GitHub repo and followed all the steps that he does. I have the gem in my gem file, I did bundle install and update and rails db:migrate and everything. However when I try running this in rails console
CommentNotification.with(post: #post).deliver(current_user)
I get
Traceback (most recent call last):
1: from (irb):1
NameError (uninitialized constant CommentNotification)
This is my comment_notification.rb class that gets generated under app/notifications/comment_notificaiton.rb when I run rails generate noticed:notification CommentNotification just as he does in the video and just as the documentation suggests.
# To deliver this notification:
#
CommentNotification.with(post: #post).deliver_later(current_user)
CommentNotification.with(post: #post).deliver(current_user)
class CommentNotification < Noticed::Base
# Add your delivery methods
#
deliver_by :database
# deliver_by :email, mailer: "UserMailer"
# deliver_by :slack
# deliver_by :custom, class: "MyDeliveryMethod"
# Add required params
#
param :post
# Define helper methods to make rendering easier.
#
def message
t(".message")
end
#
def url
post_path(params[:post])
end
end
You have to restart your spring server.
Using bin/spring stop command, the spring server will be stopped. Then the server will be started using rails server or rails s.
A bit late to this, but manually loading the notification class in rails console solved this issue in my case, i.e.: load "app/notifications/comment_notification.rb". (PS: I would also check the spelling of the file name, i.e. comment_notification vs comment_notificaiton)
Uncomment the first two lines:
# CommentNotification.with(post: #post).deliver_later(current_user)
# CommentNotification.with(post: #post).deliver(current_user)
remember, #post must be the resource that you are going to store in user notifications
user.notifications
#post must exist

"The action 'execute' could not be found for GraphqlController" when using GraphQL on an API only Rails app?

I've posted a bug for this on rmosolgo/graphql-ruby but just in case I may be doing something wrong, I'm hoping to see if anyone else has a solution to my problem.
When creating an API only rails application it seems that Rails believes the execute method in my GraphqlController is missing.
Here is my graphql_controller.rb file:
class GraphqlController < ApplicationController
# If accessing from outside this domain, nullify the session
# This allows for outside API access while preventing CSRF attacks,
# but you'll have to authenticate your user separately
protect_from_forgery with: :null_session
def execute
variables = ensure_hash(params[:variables])
query = params[:query]
operation_name = params[:operationName]
context = {
# Query context goes here, for example:
# current_user: current_user,
}
result = RailsApiGraphqlExecuteTestSchema.execute(query, variables: variables, context: context, operation_name: operation_name)
render json: result
rescue => e
raise e unless Rails.env.development?
handle_error_in_development e
end
# ... continues on
end
Here is my routes.rb file:
Rails.application.routes.draw do
post "/graphql", to: "graphql#execute"
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end
when I run rake routes this is what I get:
prompt> rake routes
Prefix Verb URI Pattern Controller#Action
graphql POST /graphql(.:format) graphql#execute
... continues on
You should be able to reproduce this with the following command line steps:
rails new execute-test --api
cd execute-test
vim Gemfile # or open an editor and add "gem 'graphql'"
bundle
rake db:create
rails g graphql:install
rake routes # to test that the route exists
rails s
When you use an app like GraphiQL and go to http://localhost:3000/graphql you'll get the following error:
Started POST "/graphql" for 127.0.0.1 at 2019-10-15 16:23:29 -0700
(0.3ms) SELECT sqlite_version(*)
AbstractController::ActionNotFound (The action 'execute' could not be found for GraphqlController):
... strack trace continues ...
Maybe I'm doing something wrong? Any help would be much appreciated.
It looks like this line in the execute method:
protect_from_forgery with: :null_session
is what caused the problem. I'll have to look into this some more. +1 and I'll even mark the answer correct if someone can figure out why this is happening.
Edit: The reason this is happening is because this method assumes you're inheriting from ActionController::Base and not ActionController::API (which doesn't have this method). the API class is supposed to be lighter and therefore doesn't support cookies/sessions out of the box.

Can't modify frozen Array error when running rspec

Had been in the process of getting a Rails Engine upgraded to Rails 5.1 and now in the process of getting the rspec tests back working.
I have a controller, and in that controller I have the following:
module Users
class SessionsController < Devise::SessionsController
skip_before_action :authenticate_user!
skip_before_action :authorize_user!
def create
super
flash[:analytics] = { "data-analytics-form-completed-name" => "#{StewardshipUser.app_slug}/sign-in", "data-analytics-form-completed-type" => "login" }
end
def repopulate_email
(params[:user] && params[:user][:email]) ? params[:user][:email] : ''
end
helper_method :repopulate_email
end
end
If I remove the skip_before_action :authorize_user! the tests run, but not all successfully.
With the line I'm getting the following error:
An error occurred while loading ./spec/validators/rfc_compliant_validator_spec.rb.
Failure/Error: Dummy::Application.initialize!
RuntimeError:
can't modify frozen Array
# /Users/ahcarpenter/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/engine.rb:579:in `unshift'
# /Users/ahcarpenter/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/engine.rb:579:in `block in <class:Engine>'
Any thoughts on why the initializer would be breaking down with that line in there?
Additionally, when I had initially gone to reinitialize rspec, I had to comment out that method to get the initializer to run as it was not found any longer for some reason (I don't seem to have bumped any gem versions up that contained that method, but maybe so)
I'm sure you've fixed this by now, but I had this error, I realized that my test database was not initialized properly. I fixed the error by running the following command:
rails db:migrate RAILS_ENV=test
I hope this is helpful for anyone who stumbles across this post.

Rails - conditionally log for a specific hostname

I'm looking for a way to configure a Rails server log only if the client has contacted a specific hostname. e.g. I could make it so that http://public.example.com doesn't get logged, but http://debug.example.com (same underlying Rails app server) does get logged (or ideally gets logged in more detail than the regular host). It would help with production debugging.
You can use gem Lograge to customize your log. This gem will give you much more custom to your log. For example, in your case, I will do this
After install the gem. Create a file at config/initializers/lograge.rb
# config/initializers/lograge.rb
Rails.application.configure do
config.lograge.enabled = true
config.lograge.custom_options = lambda do |event|
# custom log on specific domain
if event.payload[:host] == "debug.example.com"
{:host => event.payload[:host]}
else
{}
end
end
end
And in your Application Controller
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
# This will add request's host to lograge so you can use it to filter log later
def append_info_to_payload(payload)
super
payload[:host] = request.host
end
end
Now you can customize your log base on domain, on how to customize it please read at: https://github.com/roidrage/lograge

Uninitialized constant error after uploading on Heroku

There is the following problem: I'm developing some Rails application on my local machine, and all is good, app works, but after uploading on Heroku there would be the following error (I saw it using 'heroku logs'):
NameError (uninitialized constant Api::V1::ApiV1Controller::UndefinedTokenTypeError)
My code:
def require_token
begin
Some code which generates UndefinedTokenTypeError
rescue UndefinedTokenTypeError => e
render json: e.to_json
end
end
UndefinedTokenTypeError is in lib/errors.rb file:
class EmptyCookieParamsError < StandardError
def to_json
{ result_code: 1 }
end
end
class UndefinedTokenTypeError < StandardError
def to_json
{ result_code: 2 }
end
end
I've got the same version for Rails/Ruby on my local machine (2.0). How can I fix it? Thanks.
From what I can see, you may be experiencing either a CORS-related issue or you're not authenticating properly
Cross Origin Resource Sharing
CORS is a standard HTML protocol, which basically governs which websites can "ping" your site. Facebook & Twitter's third-party widgets only work because they allow any site to send them data
For Rails to work with CORS, it's recommended to install the Rack-CORS gem. This will allow you to put this code in your config/application.rb file:
#CORS
config.middleware.use Rack::Cors do
allow do
origins '*'
resource '/data*', :headers => :any, :methods => :post
end
end
Because you're experiencing these issues on Heroku, it could be the problem you're experiencing. Even if it isn't, it's definitely useful to appreciate how CORS works
Authentication
Unless your API is public, you'll likely be authenticating the requests
The way we do this is with the authenticate_or_request_with_http_token function, which can be seen here:
#Check Token
def restrict_access
authenticate_or_request_with_http_token do |token, options|
user = User.exists?(public_key: token)
#token = token if user
end
end
We learnt how to do this with this Railscast, which discusses how to protect an API. The reason I asked about your code was because the above works for us on Heroku, and you could gain something from it!
Running on Heroku will be using the production environment. Check to see what is different between environments/development.rb and environments/production.rb
You can try running your app in production mode on your local machine, rails server -e production
I am guessing your config.autoload_paths isn't set correctly. Should be in config/application.rb

Resources