In Rails 4, how can I get the path of a controller method from the console? - ruby-on-rails-4

I’m using devise 4.2 with with Rails 4.2. I have this in my routes.rb file, within a namespace
devise_scope :user do
post 'sessions' => 'sessions#create'
delete 'sessions' => 'sessions#destroy'
end
Which I believe should be mapping to this controller
class Auth::SessionsController < Devise::SessionsController
layout false
skip_before_action :verify_authenticity_token
end
From the Rails console, I would like to confirm what the path will be for the "create" method of this controller. I tried this
my-app(dev)> url_for controller: :auth_sessions, only_path: true
NoMethodError: undefined method `url_for' for main:Object
from (irb):4
from /usr/share/rvm/gems/ruby-2.4.5#my-app/gems/railties-4.2.10/lib/rails/commands/console.rb:110:in `start'
from /usr/share/rvm/gems/ruby-2.4.5#my-app/gems/railties-4.2.10/lib/rails/commands/console.rb:9:in `start'
from /usr/share/rvm/gems/ruby-2.4.5#my-app/gems/railties-4.2.10/lib/rails/commands/commands_tasks.rb:68:in `console'
from /usr/share/rvm/gems/ruby-2.4.5#my-app/gems/railties-4.2.10/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
from /usr/share/rvm/gems/ruby-2.4.5#my-app/gems/railties-4.2.10/lib/rails/commands.rb:17:in `<top (required)>'
from bin/rails:4:in `require'
from bin/rails:4:in `<main>'
my-app(dev)>
But am getting the above error.

You can access the routes in the rails console by using either app or directly Rails.application.routes:
app.url_for(controller: "auth/sessions", action: :new, only_path: true)
# => "/auth/users/sign_in"
Rails.application.routes.url_for(controller: "auth/sessions", action: :new, only_path: true)
# => "/auth/users/sign_in"

Related

Paperclip giving NameError: uninitialized constant Model::ImageUploader

I Have found a similar question:
NameError: uninitialized constant Article::ImageUploader when using Carrierwave on rails 4.1.5
But I have tried the suggestions there:
carrierwave is installed and bundle is complete
And I have double checked my models.
My user model has:
has_one :image, :as => :assetable, :class_name => "User::Image", :dependent => :destroy
And my user creation works find but as soon as I try to access the views it breaks by this code:
<%= link_to image_tag((current_user.image.nil? ? Settings.default_user_image : current_user.image.attachment.url(:thumbnail)) , :style=>'max-width:60px;', :alt=>current_user.full_name, :title=>current_user.full_name), user_path(current_user) %>
I am not sure why this broke, earlier it was working fine, only thing I can think of is, I did bundle once again when my gemfile.lock got conflicts.
This is how I replicate the issue on rails console:
2.1.1 :001 > u = User.new
2.1.1 :002 > u.build_image
NameError: uninitialized constant User::User::Image
from /home/aditya/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.0/lib/active_record/inheritance.rb:133:in `compute_type'
from /home/aditya/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.0/lib/active_record/reflection.rb:190:in `klass'
from /home/aditya/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.0/lib/active_record/reflection.rb:207:in `build_association'
from /home/aditya/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.0/lib/active_record/associations/association.rb:247:in `build_record'
from /home/aditya/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.0/lib/active_record/associations/singular_association.rb:29:in `build'
from /home/aditya/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.0/lib/active_record/associations/builder/singular_association.rb:18:in `build_image'
from (irb):2
from /home/aditya/.rvm/gems/ruby-2.1.1/gems/railties-4.1.0/lib/rails/commands/console.rb:90:in `start'
from /home/aditya/.rvm/gems/ruby-2.1.1/gems/railties-4.1.0/lib/rails/commands/console.rb:9:in `start'
from /home/aditya/.rvm/gems/ruby-2.1.1/gems/railties-4.1.0/lib/rails/commands/commands_tasks.rb:69:in `console'
from /home/aditya/.rvm/gems/ruby-2.1.1/gems/railties-4.1.0/lib/rails/commands/commands_tasks.rb:40:in `run_command!'
from /home/aditya/.rvm/gems/ruby-2.1.1/gems/railties-4.1.0/lib/rails/commands.rb:17:in `<top (required)>'
from bin/rails:4:in `require'
from bin/rails:4:in `<main>'
Please help. I am stuck at a critical point right now.
Path to the file where error is happening is:
/demo/app/views/home/index.html.erb
Image class resides in:
/demo/app/models/user/image.rb
Contents for image.rb
class User::Image < Asset
has_attached_file :attachment, {
fog_credentials: {:aws_access_key_id=>"***", :aws_secret_access_key=>"***", :provider=>"AWS"}, :fog_public=>true, :fog_directory=>"test",
styles: { :thumbnail => "60x60#", :profile => "165x165#" },
storage: :multiple,
path: ":compatible_rails_root/users/files/:id/:style.:extension",
url: "/uploads/posts/files/:id/:style.:extension",
multiple_if: lambda { |user| true },
display_from_s3: lambda { |user| true }
}
validates_attachment_content_type :attachment, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]
end
User mode is simply in
/demo/app/models
Probably, your namespaces are wrong, try to write your classes as follows (note the introduced Users module):
# app/models/users/image.rb
module Users
class Image < Asset
has_attached_file :attachment, { # ...
# ....
end
end
and just modify a line referring to the Image class in User class (the only change is that it's Users::Image now:
# app/models/users.rb
class User < ActiveRecord::Base
has_one :image, :as => :assetable, :class_name => "Users::Image", #...
# ...
end
this (and maybe one restart of the server later) and everything should be fine.

RSpec Model Testing: Failures

I am teaching myself RSpec (v3.1.7). I have installed rspec with rails g rspec:install into an existing rails app - freshly created.
I created a model: rails g rspec:model zombie. Ran the migration and all went well.
In: app/models/zombie.rb:
class Zombie < ActiveRecord::Base
validates :name, presence: true
end
In: app/spec/models/zombie_spec.rb:
require 'rails_helper'
RSpec.describe Zombie, :type => :model do
it 'is invalid without a name' do
zombie = Zombie.new
zombie.should_not be_valid
end
end
In terminal when I ran (in the app dir): rspec spec/models I get:
F
Failures:
1) Zombie is invalid without a name
Failure/Error: zombie.should_not be_valid
NoMethodError:
undefined method `name' for #<Zombie id: nil, created_at: nil, updated_at: nil>
# ./spec/models/zombie_spec.rb:6:in `block (2 levels) in <top (required)>'
Im following a video tutorial and I followed the video (Testing with RSpec) down to the latter. I'm like losing weight on the 2nd chapter. Am I missing something? Is the video using an older version of rspec for their video tutorial?
In my migration file:
class CreateZombies < ActiveRecord::Migration
def change
create_table :zombies do |t|
t.timestamps
end
end
end
Your model don't know what name is since you did not define the attribute in your migration:
class CreateZombies < ActiveRecord::Migration
def change
create_table :zombies do |t|
t.string :name
t.timestamps
end
end
end
Then run:
rake db:migrate
Then this should work fine:
z = Zombie.new(name: 'foo')
z.name
=> 'foo'
I think you are missing the name attribute. The following migration file will add name attribute to zombie model:
class AddNameToZombies < ActiveRecord::Migration
def change
add_column :zombies, :name, :string
end
end
finally run the following commands:
rake db:migrate
rake db:test:prepare
and that's it

Rails 4 Devise + Omniauth Github Routing Error

I'm using Rails 4.1.1 and I'm trying to create omniauth github with my devise gem in my application. But I get routing error, I'm following Railscast #235 revised on this topic.
Right now, I'm trying to do the same thing Ryan Bates is doing, which is raise omniauth.auth as a yaml to the screen, but I get the error:
No route matches [GET] "/auth/github/callback"
How do I fix this error?
Here you have my routes:
Rails.application.routes.draw do
devise_for :users, controllers: {omniauth_callbacks: "omniauth_callbacks"}
root to: 'questions#index'
resources :questions do
resources :answers, only: [:create]
end
resources :users, only: [:show]
#USERS CONTROLLER MY ROUTES
get "adding_likes/(:id)/(:like)/(:current_user_id)", to: "answers#adding_likes", as: :adding_likes
get "add_accept/(:answer_id)", to: "answers#accept", as: :accept
get "leaderboard", to: "users#leaderboard", as: :leaderboard
end
My controller:
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def all
raise request.env["omniauth.auth"].to_yaml
end
alias_method :github, :all
end
My user model:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :omniauthable
# :recoverable, :rememberable and :trackable
devise :database_authenticatable, :registerable, :validatable, :omniauthable
has_attached_file :avatar, :styles => { :small => "100x100>" }
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
# has_attached_file :superstarbadge, :styles => { :small => "100x100>" }
# validates_attachment_content_type :superstarbadge, :content_type => /\Aimage\/.*\Z/
has_many :questions
has_many :answers
def to_s
email
end
end
Important part of my devise.rb
config.omniauth :github,NOT-VISIBILE,IN-HERE
Basically, you haven't added the routes for it. I think you've missed Ryan add it to his routes file. Just add this:
get "/auth/github/callback" => "yourController#yourAction"
but since you're using omniauth, it's better this way
get "/auth/:provider/callback" => "yourController#yourAction
And add the necessary views for it.

fabrication gem: trouble with association used with attributes

I'm in a middle of upgrading a rails app from version 3.2.x to 4.0.8, I had a trouble with fabrication (version 2.11.3) on an ar class (Location) belongs to a Category (but also HMBT Categories), in turn a category is belongs to Typology,
class Location
belongs_to :category
has_many :location_categories
has_many :categories, through: :location_categories
validates :title, :presence => true
validates :address_city, :presence => true
validates :nation_id, :presence => true
validates :phone, :phone_format => true
validates :mobile, :phone_format => true
validates :fax, :phone_format => true
validates :email, :email_format => true
validates :url, :url_format => true, :allow_blank => true
validate :validate_category_default
validates_attachment :logo, size: { in: 0..1.megabytes }, content_type: { content_type: [ 'image/jpg', 'image/jpeg', 'image/png', 'image/gif' ]}, if: Proc.new {|a| a.logo.present? }
validates_with VersionValidator, :on => :update
private
def validate_category_default
errors.add(:category_ids, I18n.t('activerecord.errors.messages.location.category_default')) unless category_ids.detect{|category| category == category_id }
end
# other stuff...
end
class Category
belongs_to :typology
validates :typology_id, :uniqueness => { :scope => :site_id }
validates :title, :presence => true, :uniqueness => { :scope => :site_id }
validates_with VersionValidator, :on => :update
# other stuff...
end
class Typology
validates :logic_title, :presence => true, :uniqueness => true
validates_attachment :image, size: { in: 0..1.megabytes }, content_type: { content_type: [ 'image/jpg', 'image/jpeg', 'image/png', 'image/gif' ]}, if: Proc.new {|a| a.image.present? }
validates_with VersionValidator, :on => :update
# other stuff...
end
then on the fabricator relative to Location, when an object is created it trig also creation of Category and a Typology related :
Fabricator(:location) do
category(fabricator: :category)
category_ids { |attrs| [ attrs[:category][:id] ] }
# other stuff...
end
Fabricator(:category) do
typology(fabricator: :typology)
# other stuff...
end
Fabricator(:typology) do
# other stuff...
end
the situation now is that I detect a problem in the creation of location on rails 4 (on rails 3 worked fine), this is the stack trace:
from /Users/my_user/.rvm/gems/ruby-2.1.0/gems/activerecord-4.0.8/lib/active_record/validations.rb:57:in `save!'
from /Users/my_user/.rvm/gems/ruby-2.1.0/gems/activerecord-4.0.8/lib/active_record/attribute_methods/dirty.rb:41:in `save!'
from /Users/my_user/.rvm/gems/ruby-2.1.0/gems/activerecord-4.0.8/lib/active_record/transactions.rb:275:in `block in save!'
from /Users/my_user/.rvm/gems/ruby-2.1.0/gems/activerecord-4.0.8/lib/active_record/transactions.rb:330:in `block in with_transaction_returning_status'
from /Users/my_user/.rvm/gems/ruby-2.1.0/gems/activerecord-4.0.8/lib/active_record/connection_adapters/abstract/database_statements.rb:203:in `block in transaction'
from /Users/my_user/.rvm/gems/ruby-2.1.0/gems/activerecord-4.0.8/lib/active_record/connection_adapters/abstract/database_statements.rb:211:in `within_new_transaction'
from /Users/my_user/.rvm/gems/ruby-2.1.0/gems/activerecord-4.0.8/lib/active_record/connection_adapters/abstract/database_statements.rb:203:in `transaction'
from /Users/my_user/.rvm/gems/ruby-2.1.0/gems/activerecord-4.0.8/lib/active_record/transactions.rb:209:in `transaction'
from /Users/my_user/.rvm/gems/ruby-2.1.0/gems/activerecord-4.0.8/lib/active_record/transactions.rb:327:in `with_transaction_returning_status'
from /Users/my_user/.rvm/gems/ruby-2.1.0/gems/activerecord-4.0.8/lib/active_record/transactions.rb:275:in `save!'
from /Users/my_user/.rvm/gems/ruby-2.1.0/gems/fabrication-2.11.3/lib/fabrication/generator/base.rb:94:in `persist'
from /Users/my_user/.rvm/gems/ruby-2.1.0/gems/fabrication-2.11.3/lib/fabrication/generator/base.rb:26:in `create'
from /Users/my_user/.rvm/gems/ruby-2.1.0/gems/fabrication-2.11.3/lib/fabrication/schematic/definition.rb:75:in `block in fabricate'
from /Users/my_user/.rvm/gems/ruby-2.1.0/gems/fabrication-2.11.3/lib/fabrication/schematic/definition.rb:74:in `instance_eval'
from /Users/my_user/.rvm/gems/ruby-2.1.0/gems/fabrication-2.11.3/lib/fabrication/schematic/definition.rb:74:in `fabricate'
from /Users/my_user/.rvm/gems/ruby-2.1.0/gems/fabrication-2.11.3/lib/fabricate.rb:29:in `create'
from /Users/my_user/.rvm/gems/ruby-2.1.0/gems/fabrication-2.11.3/lib/fabrication.rb:62:in `Fabricate'
from (irb):18
from /Users/my_user/.rvm/gems/ruby-2.1.0/gems/railties-4.0.8/lib/rails/commands/console.rb:90:in `start'
from /Users/my_user/.rvm/gems/ruby-2.1.0/gems/railties-4.0.8/lib/rails/commands/console.rb:9:in `start'
from /Users/my_user/.rvm/gems/ruby-2.1.0/gems/railties-4.0.8/lib/rails/commands.rb:62:in `<top (required)>'
from script/rails:6:in `require'
But i don't understand what causes it.

Rails, Devise, Rspec: Undefined method 'sign_in'

I am trying to write Rspec tests in Rails, using Devise helper methods for signing in and out. The sign_in method is not working. However, it had been working earlier, before a slew of changes to the app.
Things I have tried:
I am including the test helpers in Rspec.configure.
Using Warden's login_as
Clearing the Rails cache.
Getting rid of Capybara to see if that were causing the issue
I am not setting the session explicitly in my controller specs (e.g. no valid_session)
So far, no dice. What do I need to do differently to test my controllers with a signed-in user?
Error message:
OrderItemsController GET #index renders the :index view
Failure/Error: sign_in :admin
NoMethodError:
undefined method `sign_in' for # <RSpec::ExampleGroups::OrderItemsController_2::GETIndex:0x00000102c002d0>
# ./spec/controllers/order_items_controller_spec.rb:6:in `block (2 levels) in <top (required)>'
Controller Spec
require 'spec_helper'
describe OrderItemsController do
before (:each) do
admin = create(:admin)
sign_in :admin
end
describe "GET #index" do
it "renders the :index view" do
get :index
expect( response ).to render_template :index
end
end
end
spec_helper.rb
require 'rspec/rails'
require 'capybara/rspec'
RSpec.configure do |config|
config.include ApplicationHelper
config.include ControllersHelper
config.include UsersHelper
config.include Devise::TestHelpers, type: :controller
config.include FactoryGirl::Syntax::Methods
end
Gemfile
group :development, :test do
gem 'rspec-rails', '~> 3.0.0.beta'
gem 'capybara'
gem 'factory_girl_rails'
gem 'faker'
gem 'dotenv-rails'
gem 'guard'
gem 'guard-annotate'
gem 'guard-rspec', require: false
gem 'guard-livereload', require: false
gem 'foreman'
end
factories/user.rb
FactoryGirl.define do
factory :user do
first { Faker::Name.first_name }
last { Faker::Name.last_name }
email { Faker::Internet.email }
admin false
password "secrets1"
password_confirmation "secrets1"
confirmed_at Date.today
factory :admin do
admin true
end
end
end
Thanks in advance.
Did you recently upgrade to RSpec 3 like I did? This is from the RSpec 3 documentation:
Automatically Adding Metadata
RSpec versions before 3.0.0 automatically added metadata to specs based on
their location on the filesystem. This was both confusing to new users and not
desirable for some veteran users.
In RSpec 3, this behavior must be explicitly enabled:
​# spec/rails_helper.rb
RSpec.configure do |config|
config.infer_spec_type_from_file_location!
end
Since this assumed behavior is so prevalent in tutorials, the default
configuration generated by rails generate rspec:install enables this.
If you follow the above listed canonical directory structure and have
configured infer_spec_type_from_file_location!, RSpec will automatically
include the correct support functions for each type.
After I add that configuration snippet, I no longer have to specify the spec type (e.g. type: :controller).
I figured out a solution. I explicitly defined the controller's Describe block as a controller type.
describe OrderItemsController, :type => :controller do
I still don't understand why this code worked earlier but now needs this (seemingly redundant) explicit declaration. Regardless, I'd appreciate learning what happened here. Thanks!
I can provide you an example (works for me - rspec / capybara / simplecov etc..)
spec/spec_helper.rb
require 'capybara/rspec'
require 'capybara/rails'
RSpec.configure do |config|
config.use_transactional_fixtures = true
config.infer_base_class_for_anonymous_controllers = false
config.include FactoryGirl::Syntax::Methods
config.include Devise::TestHelpers, type: :controller
config.include Capybara::DSL
config.include Warden::Test::Helpers
config.include Rails.application.routes.url_helpers
end
spec/integration/user_flow_spec.rb
require 'spec_helper'
feature 'Verify contract' do
# Create employee
let(:employee) { create(:employee) }
let (:book) { create(:book) }
# Sign in employee before each test!
before :each do
login_as employee, scope: :user
end
scenario 'create book' do
# Visit Index and click to create
visit employee_books_path
click_link 'Create'
expect(current_path).to eq(employee_books_path)
end
end
I hope it will be ok :) I think your problem is missing Warden test helpers...
You can use the Devise helper in the file spec/spec_helper.rb:
RSpec.configure do |config|
config.include Devise::TestHelpers, type: :controller
end
If you need the sign_in method in a request spec file, then you should include this:
config.include Devise::Test::IntegrationHelpers, type: :request
For Rails 5 and Rspec 3 you need to add this into your spec_helper.rb
config.include Devise::Test::ControllerHelpers, type: :controller
You can use login_as method instead like this:
# rails_helper.rb
RSpec.configure do |config|
config.include Warden::Test::Helpers
end
In your spec file use:
#spec/integration/user_flow_spec.rb
before :each do
employee = create(:employee)
login_as employee, scope: :user
end