Writing ROR application, trying to add Facebook "recommend" to article - ruby-on-rails

General problem. Working on a ROR app hosted on Heroku. However I am getting the error in local environment. For Articles I wish users to be able to "recommend" the article via Facebook and display number of "recommends" the Article has recieved.
I have a ROR application on Heroku and have set up a Facebook app with minimum info.
Where/how do I add in the Facebook info he ROR application.
I have tried a number of different things including
(1) adding some info to config/environment/development e.g.
# Facebook stuff
config.fb_app_id = 257669251071656
config.fb_app_secret = 7b53604575d5dc0259466cfd41808c93
which gives error
/Users/davidlee/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-4.0.4/lib/active_support/dependencies.rb:229:in `require': /Volumes/F Drive/drill_investor/config/environments/development.rb:49: syntax error, unexpected tIDENTIFIER, expecting keyword_end (SyntaxError)
Should I be adding a config/initializers/facebook.rb file and/or changes in config/environments/development…production. If so what goes into the onfig/initializers/facebook.rb file ?
At the moment I have some stuff set up for devise and paperclip in these directories - however this was all copied and haven't figured out how it actually works.
any help appreciated
Pierre
The new whole config/application.rb file, with comments removed, is below
require File.expand_path('../boot', __FILE__)
require 'rails/all'
Bundler.require(:default, Rails.env)
module DrillInvestor
class Application < Rails::Application
# pmlc
ActsAsTaggableOn.force_lowercase = true
ActsAsTaggableOn.remove_unused_tags = true
config.fb_app_id = ENV["FACEBOOK_APP"]
config.fb_app_secret = ENV["FACEBOOK_SECRET"]
# pmlc
end
end

The environment files of Rails are meant to give you a place to specific environment-specific settings -- such as different asset paths, Gem settings, etc to use
Error
Your error basically says your development.rbfile is not formatted correctly (you should post the whole file). You'll need to be able to set it out correctly - I'd even recommend putting the details into application.rb:
#config/application.rb
config.fb_app_id = ENV["FACEBOOK_APP"]
config.fb_app_secret = ENV["FACEBOOK_SECRET"]
#config/application.yml -> from Figaro
FACEBOOK_APP: 257669251071656
FACEBOOK_SECRET: 7b53604575d5dc0259466cfd41808c93
Figaro
I'd recommend using Figaro to keep your sensitive data behind closed doors. It allows you to create environment variables on both local & production environments
I think this should solve your issue, but it will definitely help to post your development.rb

Related

Zeitwerk error on devise mailer in production environment

I have Rails 6, my preview class located in
mailer/previews/devise_mailer_preview.rb:
class DeviseMailerPreview < ActionMailer::Preview
...
end
And when I run application locally, everything is going fine, I can see my email previews on http://localhost:3000/rails/mailers/devise_mailer/confirmation_instructions address. But now Im trying to deploy application on server, and found that when I run bundle exec rails c production, I got the error:
/home/deploy/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/zeitwerk-2.3.0/lib/zeitwerk/loader/callbacks.rb:17:in
`on_file_autoloaded': expected file
/home/deploy/project/releases/20200627024908/app/mailer/previews/devise_mailer_preview.rb
to define constant Previews::DeviseMailerPreview, but didn't
(Zeitwerk::NameError)
After that I've checked locally RAILS_ENV=production rails c, and got same.
If I will rename DeviseMailerPreview class to Previews::DeviseMailerPreview, it will be broken and I cannot see emails on development, because Rails 6, accordingly to docs, expect exactly that name.
More of that, I've found in this article, that zeitwerk can be configured with autoload_paths param to avoid ruby's NameError. I found that I have it my config/application.rb:
config.load_defaults 6.0
Anyway I tried to add same row in my config/environments/production.rb file, but it didn't help.
What am I doing wrong and how can I fix it? Thanks in advance!
Add preview_path to the autoload_paths and zeitwerk will expect DeviseMailerPreview constant to be defined.
# development.rb
config.action_mailer.preview_path = Rails.root.join("app/mailers/previews")
# application.rb
config.autoload_paths << Rails.root.join("app/mailers/previews")
Your Mailer preview file is located in mailer/previews/devise_mailer_preview.rb, so I'm assuming it's full path is app/mailer/previews/devise_mailer_preview.rb
The docs says
In the above example, the preview class for UserMailer should be named UserMailerPreview and located in test/mailers/previews/user_mailer_preview.rb
So put your devise_mailer_preview.rb file to test/mailers/previews/devise_mailer_preview.rb
or in your config/application.rb add this line and restart:
config.action_mailer.preview_path = "#{Rails.root}/app/mailers/previews"
Actually the answer was in the docs itself.
In Rails 6, previews are added to the autoload paths only if options.show_previews is true, which is not by default in the production environment. See the source code here.
The reason for this is that previews are supposed to be an aid for development, and they are generally not something you want to be able to look at in production.
However, you can set that flag to true in production if you want.
There's another derivative: By storing the previews under app/mailers, Rails is going to eager load them because app/mailers is in the autoload paths. If app/mailers/previews is not in the autoload paths, eager loading will fail due to the namespace mismatch. Either you have them enabled in all environments, or else is better to have them in a separate location, like the default.

Error starting Rails server: "unexpected .."

I set up a Rails app on OpenShift and pulled the default code. When I tried running it, I got the following error:
C:/Development/Ruby/lib/ruby/gems/2.3.0/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:241:in `load': C:/HEATH3N/FirstApp/config/initializers/session_store.rb:1: syntax error, unexpected .. (SyntaxError)
../../.openshift/lib/session_store.rb
I'm unclear as to what the problem is. I looked at the problematic file and don't see anything wrong. I found other questions on Stack Overflow asking about another problem with the file (the new hash style isn't supported on older Ruby versions) but I'm using Ruby 2.3 (Rails 4.1.4) and my error is different.
require File.join(Rails.root,'lib','openshift_secret_generator.rb')
# Be sure to restart your server when you modify this file.
# Set token based on intialize_secret function (defined in initializers/secret_generator.rb)
Rails.application.config.session_store :cookie_store, :key => initialize_secret(
:session_store,
'_railsapp_session'
)
# Use the database for sessions instead of the cookie-based default,
# which shouldn't be used to store highly confidential information
# (create the session table with "rails generate session_migration")
# RailsApp::Application.config.session_store :active_record_store
Try something like so -
require File.expand_path(‘../lib/openshift_secret_generator.rb‘, __FILE__)
or
require Rails.root.join('lib', 'openshift_secret_generator.rb').to_s
Please do update if either or both work for you.

Access APP_CONFIG['var'] inside routes? or supply routes with variables?

I need to do in rails 4 supply some ip address to set a constraint on certain routes.
Is there a way to get this data from a config file without harcoding it into the routes file?
Im using a yaml file and initializer for app variables like:
APP_CONFIG = YAML.load_file("#{Rails.root}/config/application.yml")[Rails.env]
so normally I could do:
constraints(:ip => %w[APP_CONFIG['app_url']]) do
.. my routes..
end
This fails in the routes.rb is there a way to fix this?
The routes.rb file is a ruby file which is instantiated once, and loaded into memory.
You can just add the ruby code inside it and it will be executed once:
Rails.application.routes.draw do
app_config = YAML.load_file("#{Rails.root}/config/application.yml")[Rails.env]
constraints(:ip => %w[app_config['app_url']]) do
.. my routes..
end
end
This will instantiate the routes.rb file with the variable loaded from the yml and available throughout your rails routes app. You don't even need to use a env variable. Local variable seems a better idea.
You can also put logic inside and make it environment dependant:
if Rails.env.production?
app_config = YAML.load_file("#{Rails.root}/config/application.yml")[Rails.env]
constraints(:ip => %w[app_config['app_url']]) do
.. my routes..
end
else
.. my routes ...
end
Taking a look at the initialization process of rails (http://guides.rubyonrails.org/initialization.html). You'll see that routing is actually loaded quite early (and earlier than application.rb or other initializers). It has therefore not yet loaded this file.
A way round this would be to place this into your boot.rb:
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
#Now load app config:
require 'yaml'
APP_CONFIG = YAML.load_file(File.expand_path('../../config/application.yml', __FILE__))
I believe you are running into a load order issue. You could probably hack around this, but...
I would highly recommend using Figaro to solve this problem. It is a gem specifically designed for rails configuration and will work nicely with 12 factor app deployments (like Heroku): https://github.com/laserlemon/figaro
I am using Figaro in the app I am currently working on and was able to confirm access to the env variables within my routes file. I believe this gem will solve your current issue and other config issues you don't even know you have yet!

Local gem class is not found in Rails application

I have written a generator which creates the following ruby file and folder:
app/tests/test.rb
in the test.rb file I have a Test class which looks like this:
class Test < MyCustomModule::MyCustomClass::Base
...
end
Now, I want to use its functionality in one of the show.html.erb files creating new instance like this:
Test.new(...).render(...).html_safe
but I am getting the following error:
uninitialized constant MyCustomModule::MyCustomClass::Base
I have use the following answer to link my gem and my rails application. It seems to work as I am able to use the generator, but the gem module and class are not seen in the rails application.
Could anyone tell how to fix this issue?
I have try to follow the tips posted here but still nothing changed:
Adding config.autoload_paths += Dir["#{config.root}/lib/**/"] in application.rb file
I have created my gem structure looking at CarrierWave gem, so the naming should be correct
I try to disable config.threadsafe! but it is already disabled since config.cache_classes and config.eager_load are set to false in development
DEPRECATION WARNING: config.threadsafe! is deprecated. Rails
applications behave by default as thread safe in production as long as
config.cache_classes and config.eager_load are set to true.
Also, looking at adding-asset-to-your-gems rails documentation, it is said that:
A good example of this is the jquery-rails gem which comes with Rails
as the standard JavaScript library gem. This gem contains an engine
class which inherits from Rails::Engine. By doing this, Rails is
informed that the directory for this gem may contain assets and the
app/assets, lib/assets and vendor/assets directories of this engine
are added to the search path of Sprockets.
So, I have done this, and put my model class file in assets folder, but the result is the same.
The following screenshots demonstrate my real case:
The screenshot below displays my gem file structure
Here you can see how I am loading the gem in my Rails application Gemfile:
gem 'thumbnail_hover_effect', '0.0.3', github: 'thumbnail_hover_effec/thumbnail_hover_effec', branch: 'master'
Then I am using the gem generator a ruby file with a cutstom name in app/thumbnails/test.rb folder with the following code:
class Test < ThumbnailHoverEffect::Image::Base
...
end
and trying to use the Test class gives me uninitialized constant ThumbnailHoverEffect::Image::Base error.
Back in the gem files, these are how the thumbnail_hover_effect file looks like
require 'thumbnail_hover_effect/version'
require 'thumbnail_hover_effect/engine'
require 'thumbnail_hover_effect/image'
module ThumbnailHoverEffect
# Your code goes here...
end
and hoe the image file looks like:
module ThumbnailHoverEffect
#
class Image
...
end
end
From what you've posted here there is no ThumbnailHoverEffect::Image::Base defined. Rails autoloading conventions (which you should not be depending on a gem btw, more on that later) would be looking for this file in thumbnail_hover_effect/image/base.rb, but the directory structure you printed does not have that. Of course you could define the class in thumbnail_hover_effect/image.rb and it would work, but the abridged snippet you posted does not show that. So where is ThumbnailHoverEffect::Image::Base defined?
If it's in thumbnail_hover_effect/image/base.rb then that would indicate the file is not being loaded. You can sanity check this by putting a puts 'loading this stupid file' at the top of thumbnail_hover_effect/image/base.rb. That will allow you to bisect the problem by seeing whether there is a problem with your definition of the class, or whether the problem is with loading the proper files. Debugging is all about bisecting the problem.

Where do you put your Rack middleware files and requires?

I'm in the process of refactoring some logic built into a Rails application into middleware, and one annoyance I've run into is a seeming lack of convention for where to put them.
Currently I've settled on app/middleware but I could just as easily move it to vendor/middleware or maybe vendor/plugins/middleware...
The biggest problem is having to require the individual files at the top of config/environment.rb
require "app/middleware/system_message"
require "app/middleware/rack_backstage"
or else I get uninitialized constant errors on the config.middleware.use lines. That could get messy very quickly. I'd rather this was tucked away in an initializer somewhere.
Is there a conventional place to put this stuff?
The specific answer I'm looking for with this bounty is: where can I put the require lines so that they are not cluttering the environment.rb file but still get loaded before the config.middleware.use calls? Everything I have tried leads to uninitialized constant errors.
Update: Now that we're using Rails 3.0, I treat a Rails app like any other Rack app; code files for middleware go in lib (or a gem listed in Gemfile) and are required and loaded in config.ru.
As of Rails 3.2, Rack middleware belongs in the app/middleware directory.
It works "out-of-the-box" without any explicit require statements.
Quick example:
I'm using a middleware class called CanonicalHost which is implemented in app/middleware/canonical_host.rb. I've added the following line to production.rb (note that the middleware class is explicitly given, rather than as a quoted string, which works for any environment-specific config files):
config.middleware.use CanonicalHost, "example.com"
If you're adding middleware to application.rb, you'll need to include quotes, as per #mltsy's comment.
config.middleware.use "CanonicalHost", "example.com"
You can put it in lib/tableized/file_name.rb. As long as the class you're trying to load is discoverable by its filename, Rails will automatically load the file necessary. So, for example:
config.middleware.use "MyApp::TotallyAwesomeMiddleware"
You would keep in:
lib/my_app/totally_awesome_middleware.rb
Rails catches const_missing and attemts to load files corresponding to the missing constants automatically. Just make sure your names match and you're gravy. Rails even provides nifty helpers that'll help you identify the path for a file easily:
>> ChrisHeald::StdLib.to_s.tableize.singularize
=> "chris_heald/std_lib"
So my stdlib lives in lib/chris_heald/std_lib.rb, and is autoloaded when I reference it in code.
In my Rails 3.2 app, I was able to get my middleware TrafficCop loading by putting it at app/middleware/traffic_cop.rb, just as #MikeJarema described. I then added this line to my config/application.rb, as instructed:
config.middleware.use TrafficCop
However, upon application start, I kept getting this error:
uninitialized constant MyApp::Application::TrafficCop
Explicitly specifying the root namespace didn't help either:
config.middleware.use ::TrafficCop
# uninitialized constant TrafficCop
For some reason (which I've yet to discover), at this point in the Rails lifecycle, app/middleware wasn't included in the load paths. If I removed the config.middleware.use line, and ran the console, I could access the TrafficCop constant without any issue. But it couldn't find it in app/middleware at config time.
I fixed this by enclosing the middleware class name in quotes, like so:
config.middleware.use "TrafficCop"
This way, I would avoid the uninitialized constant error, since Rails isn't trying to find the TrafficCop class just yet. But, when it starts to build the middleware stack, it will constantize the string. By this time, app/middleware is in the load paths, and so the class will load correctly.
For Rails 3:
#config/application.rb
require 'lib/rack/my_adapter.rb'
module MyApp
class Application < Rails::Application
config.middleware.use Rack::MyAdapter
end
end
I'm not aware of a convention, but why not put it in the /lib directory? Files in there get automatically loaded by Rails.
You could create an initializer which requires the necessary files and then leave the files wherever you want.
According to this the initializers are executed before the rack middleware is loaded.
The working solution I have so far is moving the middleware requires to config/middleware.rb and requiring that file in environment.rb, reducing it to a single require which I can live with.
I'd still like to hear how other people have solved this seemingly basic problem of adding middleware to Rails.

Resources