I'm using Devise to manage users and my goal get the current user to be saved with the created record.
I have tried to save the current user in the controller or in the _form, but either ways it has failed!
Thank you all for your help.
My record Model
class Record < ActiveRecord::Base
#Associations
belongs_to :user
# Validations
validates :title, :user, presence: true
end
My record Controller
class RecordsController < ApplicationController
before_action :find_record, only: [:show, :edit, :update, :destroy]
def create
#record = Record.new(record_params)
if #record.save
redirect_to #record
else
#records = Record.all
render 'index'
end
end
def update
if #record.update(record_params)
flash[:notice] = "The record was updated successfully"
redirect_to #record
else
render 'edit'
end
end
private
def find_record
#record = Record.find(params[:id])
end
def record_params
params.require(:record).permit(:title, :description, :user_id).merge(user: current_user) # as suggested
end
end
My Rspec
require 'rails_helper'
describe RecordsController do
let(:record) { create(:record) }
let(:user) { create(:user) }
let(:title) { "Some title I would like to put in my record" }
let(:description) { "description I would like to put in my record" }
describe "#create" do
it "creates a new record with the given title and description" do
expect do
post :create, record: { title: title, description: description, user_id: user }
end.to change { Record.count }.by(1)
expect(response).to redirect_to(assigns[:record])
expect(assigns[:record].title).to eq(title)
expect(assigns[:record].description).to eq(description)
end
it "fails to create a record and returns to the index page" do
expect(post :create, record: { description: description }).to render_template(:index)
expect(assigns[:records]).to eq(Record.all)
end
end
describe "#update" do
it "find the records and sets the new given values" do
put :update, { id: record.id, record: { title: title, description: description } }
record.reload
expect(record.title).to eq(title)
expect(record.description).to eq(description)
expect(flash[:notice]).to eq("The record was updated successfully")
end
it "fails to create a record and returns to the edit page" do
expect(put :update, { id: record.id, record: { title: "" } }).to render_template(:edit)
end
end
end
Now with the current user being saved Rspec throws me errors in create and update:
1) RecordsController#create creates a new record with the given title and description
Failure/Error: post :create, record: { title: title, description: description, user_id: user }
NoMethodError:
undefined method `authenticate' for nil:NilClass
# ./app/controllers/records_controller.rb:42:in `record_params'
# ./app/controllers/records_controller.rb:9:in `create'
# ./spec/controllers/records_controller_spec.rb:36:in `block (4 levels) in <top (required)>'
# ./spec/controllers/records_controller_spec.rb:35:in `block (3 levels) in <top (required)>'
# -e:1:in `<main>'
2) RecordsController#create fails to create a record and returns to the index page
Failure/Error: expect(post :create, record: { description: description }).to render_template(:index)
NoMethodError:
undefined method `authenticate' for nil:NilClass
# ./app/controllers/records_controller.rb:42:in `record_params'
# ./app/controllers/records_controller.rb:9:in `create'
# ./spec/controllers/records_controller_spec.rb:46:in `block (3 levels) in <top (required)>'
# -e:1:in `<main>'
3) RecordsController#update find the records and sets the new given values
Failure/Error: put :update, { id: record.id, record: { title: title, description: description } }
NoMethodError:
undefined method `authenticate' for nil:NilClass
# ./app/controllers/records_controller.rb:42:in `record_params'
# ./app/controllers/records_controller.rb:20:in `update'
# ./spec/controllers/records_controller_spec.rb:62:in `block (3 levels) in <top (required)>'
# -e:1:in `<main>'
4) RecordsController#update fails to create a record and returns to the edit page
Failure/Error: expect(put :update, { id: record.id, record: { title: "" } }).to render_template(:edit)
NoMethodError:
undefined method `authenticate' for nil:NilClass
# ./app/controllers/records_controller.rb:42:in `record_params'
# ./app/controllers/records_controller.rb:20:in `update'
# ./spec/controllers/records_controller_spec.rb:72:in `block (3 levels) in <top (required)>'
To add to bo-oz's answer (which should work), you also need to look into foreign keys. Trying to set record_id in your record form simply won't work, and I think demonstrates a misunderstanding in your interpretation of how the system works with this important piece of technology.
Specifically, you need to make sure your user_id attribute is populated before you save the new record. This is a relational database specification, not Rails:
Each time you create an association in Rails, it has to have foreign keys set in the database to enable ActiveRecord (the object association builder inside Rails) to combine the appropriate data together:
#app/models/user.rb
class User < ActiveRecord::Base
has_many :records
end
#app/models/record.rb
class Record < ActiveRecord:Base
#see diagram above -- this has to have user_id in the schema :)
belongs_to :user
end
--
The problem you're having is that you're not setting your user foreign key when you create a record.
Your records table should have a user_id foreign key, so that when Rails pulls out a Record object, it will be able to find the User who's associated to it.
As bo-oz explained, you can achieve this by setting #record.user, you can also set it in the params:
#app/controllers/records_controller.rb
class RecordsController < ApplicationController
def create
#record = Record.new record_params
#record.save ..........
end
private
def record_params
params.require(:record).permit(......).merge(user: current_user)
end
end
Both these answers would set the appropriate foreign key inside your new Record object.
You forgot to assign the user to the new record:
def create
#record = Record.new(record_params)
#record.user = current_user
if #record.save
redirect_to #record
else
#records = Record.all
render 'index'
end
end
Related
Using Rails 5.1.4, Ruby 2.4.1, rspec
Scenario:
In article destroy allow only user current_ma_user with role "a,m"
Then:
Check if current_ma_user.role = "a,m"
or current_ma_user own article (#article.user)
So I create current_ma_user as hash as well as user.
Then call role to check what is user[role ]
Problems:
How to add new method to hash.
How to pass that hash.method from rspec controller_spec to controller.
Failures:
1) ArticlesController DELETE #destroy destroys the requested article
Failure/Error: delete :destroy, params: {id: article.to_param}, session: valid_session, :current_ma_user.role => "a,m"
NoMethodError:
undefined method `role' for :current_ma_user:Symbol
# ./spec/controllers/articles_controller_spec.rb:172:in `block (4 levels) in <top (required)>'
# ./spec/controllers/articles_controller_spec.rb:171:in `block (3 levels) in <top (required)>'
This is the gist
articles_controller_spec.rb:
require 'rails_helper'
RSpec.describe ArticlesController, type: :controller do
class Hash #patch to temp pass problem 1
def role
"a,m" #Hard Code, need to call user["role"] need code
end
end
user = {}
user["uid"] = "admin"
user["provider"] = "Facebook"
user["email"] = "1.0#kul.asia"
user["role"] = "a,m"
current_ma_user = user
describe "DELETE #destroy" do
it "destroys the requested article" do
article = Article.create! valid_attributes
expect {
delete :destroy, params: {id: article.to_param}, session: valid_session
}.to change(Article, :count).by(-1)
end
it "redirects to the articles list" do
article = Article.create! valid_attributes
delete :destroy, params: {id: article.to_param}, session: valid_session
expect(response).to redirect_to(articles_url)
end
end
end
Controller:
class ArticlesController < ApplicationController before_action :load_article, only: [:show, :destroy]
def destroy
if current_ma_user.role.upcase.split(',').include?("A") || current_ma_user == #article.user
#if current_ma_user == #article.user
#article.destroy
end
redirect_to :action=>'index' end
private
def load_article
#article = Article.find(params[:id]) end
end
Updated with line number:
Updated debug to show value of current_ma_user in .spec and controller
This is where your error is coming from (in your controller):
if current_ma_user.role.upcase.split(',').include?("A") || current_ma_user == #article.user
Suggested Solutions
Where is current_ma_user defined in the controller? (if it’s not assigned, then it needs to be assigned before you call the role method on the current_ma_user variable.
Try that and see how it goes.
Do something like this:
current_ma_user = User.find( params[:user_id])
Now you seem to want to pass something into the params hash. Remember to white list whatever you decide to pass into params. Whether it is user id or roles id etc, or a roles string.
When writing your tests, pass in the approrpiate values to the params hash. If you are passing in a user_id in your test, then you will have to make sure that a user is created in the test.
delete :destroy, {:id => article.id.to_s, :user_id => #current_ma_user.id }, session: valid_session
also perhaps in your spec file, in your test, put the current_ma_user in a before filter and make it an instance variable so it will be accessible to all your tests:
before(:each) do
#current_ma_user = user.create( <--- create the user with the
appropriate attributes here --->)
end
Warning: Untested
I just typed it into the stack overflow editor.
I'm using latest version of Solidus e-commerce (fork of Spree) and I'm having this issue. To describe it quickly:
In Admin I create Spree::Membership record
after_save callback in Spree::Membership creates Product and 2 variants
This code works when I run the server, but when I'm trying to use Rspec it gives me this error:
Failure/Error: reload.product.setup_membership_variants
NoMethodError:
undefined method `setup_membership_variants' for nil:NilClass
# ./app/models/spree/membership.rb:26:in `block in setup_product'
# ./app/models/spree/membership.rb:18:in `setup_product'
# /box/gems/factory_girl-4.8.0/lib/factory_girl/configuration.rb:18:in `block in initialize'
# /box/gems/factory_girl-4.8.0/lib/factory_girl/evaluation.rb:15:in `create'
# /box/gems/factory_girl-4.8.0/lib/factory_girl/strategy/create.rb:12:in `block in result'
# /box/gems/factory_girl-4.8.0/lib/factory_girl/strategy/create.rb:9:in `tap'
# /box/gems/factory_girl-4.8.0/lib/factory_girl/strategy/create.rb:9:in `result'
# /box/gems/factory_girl-4.8.0/lib/factory_girl/factory.rb:42:in `run'
# /box/gems/factory_girl-4.8.0/lib/factory_girl/factory_runner.rb:29:in `block in run'
# /box/gems/factory_girl-4.8.0/lib/factory_girl/factory_runner.rb:28:in `run'
# /box/gems/factory_girl-4.8.0/lib/factory_girl/strategy_syntax_method_registrar.rb:20:in `block in define_singular_strategy_method'
# ./spec/controllers/spree/premium_controller_spec.rb:4:in `block (2 levels) in <top (required)>'
# ./spec/controllers/spree/premium_controller_spec.rb:33:in `block (6 levels) in <top (required)>'
# ./spec/controllers/spree/premium_controller_spec.rb:53:in `block (8 levels) in <top (required)>'
# ./spec/controllers/spree/premium_controller_spec.rb:53:in `block (7 levels) in <top (required)>'
Here is code I'm using:
membership.rb
class Spree::Membership < Spree::Base
has_many :active_memberships, class_name: 'Spree::ActiveMembership', dependent: :destroy
has_one :membership_product, class_name: "Spree::MembershipProduct", dependent: :destroy
has_one :product, through: :membership_product, source: :product
validates :name, presence: true
validates :monthly_quota, presence: true
validates :price, presence: true
after_save :setup_product
private
def setup_product
if product.nil?
ActiveRecord::Base.transaction do
create_membership_product(
product: Spree::Product.create(
name: name,
price: price,
shipping_category: Spree::ShippingCategory.find_by(name: "Default")
)
)
reload.product.setup_membership_variants
end
else
product.update(name: name, price: price)
end
end
end
product_decorator.rb
Spree::Product.class_eval do
def setup_membership_variants
ot = Spree::OptionType.find_or_create_by(name: "Membership")
option_types << ot
if ot.option_values.empty?
["Monthly", "Yearly"].each do |freq|
ot.option_values.create(name: freq, presentation: freq)
end
end
month = variants.create(is_master: false, price: price, track_inventory: false)
month.option_values << Spree::OptionValue.find_by(name: "Monthly")
year = variants.create(is_master: false, price: price * 12, track_inventory: false)
year.option_values << Spree::OptionValue.find_by(name: "Yearly")
end
end
membership.rb factory
FactoryGirl.define do
factory :membership, class: Spree::Membership do
name {FFaker::Lorem.word}
monthly_quota { rand(10..200) }
price { rand(10..200) }
trait :unnamed do
name nil
end
trait :without_quota do
monthly_quota nil
end
trait :priceless do
price nil
end
end
end
example of controller test
require 'rails_helper'
RSpec.describe Spree::PremiumController, type: :controller do
let(:valid_membership) { create(:membership) }
let(:variant) { create(:master_variant) }
context "#show" do
it "returns http success" do
get :show
expect(response).to have_http_status(:success)
end
it "returns all memberships" do
get :show
expect(assigns[:memberships]).to include(valid_membership)
end
end
context "#create" do
let!(:store) { create(:store) }
context "user not logged" do
context "valid attributes" do
context "user doesn't exist in database" do
subject do
post(:create, params: {
premium: {
first_name: "Ondrej",
last_name: "Kubala",
email: "ondrej#bala.com",
password: "test123",
password_confirmation: "test123",
membership_id: valid_membership.id,
payment_frequency: "1", #monthly yearly is 2
cc_number: "4111111111111111",
cc_exp_date: "10/22",
cvv: "123"
}
})
end
it "creates user with valid attributes" do
expect { subject }.to change { Spree::User.count }.from(0).to(1)
end
it "logs in user" do
expect(controller.warden).to receive(:set_user)
subject
end
context "create order with variant" do
it "should handle population" do
expect { subject }.to change { Spree::Order.count }.by(1)
user = Spree::User.find_by email: "ondrej#bala.com"
order = user.orders.last
expect(response).to redirect_to go_premium_path
expect(order.line_items.size).to eq(1)
# line_item = order.line_items.first
# expect(line_item.variant_id).to eq(valid_membership.reload.product.variants.)
end
it "charges credit card"
it "should redirect to account page"
end
end
context "user already exists"
end
context "wrong user attributes" do
end
context "wrong payment attributes" do
end
end
context "user is logged in" do
let(:user) { create(:user) }
before do
allow(controller).to receive_messages try_spree_current_user: user
allow(controller).to receive_messages spree_current_user: user
end
it "doesn't create user"
end
end
end
I don't have too much experience in Rspec, but it's weird that it works when server is running in development but in test it gives me that error.
Any idea what is wrong?
My guess would be that product creation call fails for some reason.
Try bang version(product: Spree::Product.create!) to have the error thrown when it occurs.
If product indeed gets created, use pry or byebug to figure out why after reload membership, product is not associated with membership.
I do not write tests very well and I have some trouble using instance variable from Application Controller for another controllers in test.
In Rails I had a pretty simple controller action.
def index
#cities = City.all
#starred_cities = #cities.where(starred: true)
end
For this action I have a test:
RSpec.describe CitiesController, :type => :controller do
let(:city) { create(:city) }
describe 'GET #index' do
let(:cities) { create_list(:city, 2) }
before { get :index }
it 'populates an array of all cities' do
expect(assigns(:cities)).to match_array(cities)
end
it 'renders index view' do
expect(response).to render_template :index
end
end
end
In application I need to get a country by domain name and set globally for all controllers. I add to ApplicationController before_action method like this:
before_action :get_country
def get_country
country_slugs = {en: 'usa', ru: 'russia', es: 'spain'}
current_country_slug = country_slugs[I18n.locale]
#country = Country.find_by_slug(current_country_slug)
end
And now I can get cities in my controller only for current country:
def index
#cities = #country.cities
#starred_cities = #cities.where(starred: true)
end
Now I have some trouble because my controller test fails with exception:
Failures:
1) CitiesController GET #index populates an array of all cities
Failure/Error: #cities = #country.cities
NoMethodError:
undefined method `cities' for nil:NilClass
# ./app/controllers/cities_controller.rb:5:in `index'
# ./spec/controllers/cities_controller_spec.rb:9:in `block (3 levels) in <top (required)>'
2) CitiesController GET #index renders index view
Failure/Error: #cities = #country.cities
NoMethodError:
undefined method `cities' for nil:NilClass
# ./app/controllers/cities_controller.rb:5:in `index'
# ./spec/controllers/cities_controller_spec.rb:9:in `block (3 levels) in <top (required)>'
Please help, what should I do to combine such instance variable and make an association on it?
You have to set up all associations used in the testcase properly, in your case the country with assigned cities is missing (thus nil.cities is called) or mock the methods to return the objects as AR would return them, like:
RSpec.describe CitiesController, :type => :controller do
describe '#index' do
let(:cities) { double('cities') }
let(:starred_cities) { double('starred_cities') }
let(:country) { double('country', cities: cities) }
before do
allow(cities).to receive(:where).with(starred: true).and_return(starred_cities)
allow(Country).to receive(:find_by_slug).and_return(country)
get :index
end
it 'populates an array of all cities' do
expect(assigns(:cities)).to match_array(cities)
end
it 'renders index view' do
expect(response).to render_template :index
end
end
end
Mocking can be quite usefull if you know what you are doing to prevent hitting the db (slow!) since AR is already quite tested well. But also can let you write passing tests although your implementation has bugs, so use it wisely.
I'm using Devise to manage users and my goal get the current user to be saved with the created record.
The current user is saved in the controller but my Rspec is wrong!
Thank you all for your help.
My record Model
class Record < ActiveRecord::Base
#Associations
belongs_to :user
# Validations
validates :title, :user, presence: true
end
My record Controller
class RecordsController < ApplicationController
before_action :find_record, only: [:show, :edit, :update, :destroy]
def create
#record = Record.new(record_params)
if #record.save
redirect_to #record
else
#records = Record.all
render 'index'
end
end
def update
if #record.update(record_params)
flash[:notice] = "The record was updated successfully"
redirect_to #record
else
render 'edit'
end
end
private
def find_record
#record = Record.find(params[:id])
end
def record_params
params.require(:record).permit(:title, :description, :user_id).merge(user: current_user) # as suggested
end
end
My Rspec
require 'rails_helper'
describe RecordsController do
let(:record) { create(:record) }
let(:user) { create(:user) }
let(:title) { "Some title I would like to put in my record" }
let(:description) { "description I would like to put in my record" }
describe "#create" do
it "creates a new record with the given title and description" do
expect do
post :create, record: { title: title, description: description, user_id: user }
end.to change { Record.count }.by(1)
expect(response).to redirect_to(assigns[:record])
expect(assigns[:record].title).to eq(title)
expect(assigns[:record].description).to eq(description)
end
it "fails to create a record and returns to the index page" do
expect(post :create, record: { description: description }).to render_template(:index)
expect(assigns[:records]).to eq(Record.all)
end
end
describe "#update" do
it "find the records and sets the new given values" do
put :update, { id: record.id, record: { title: title, description: description } }
record.reload
expect(record.title).to eq(title)
expect(record.description).to eq(description)
expect(flash[:notice]).to eq("The record was updated successfully")
end
it "fails to create a record and returns to the edit page" do
expect(put :update, { id: record.id, record: { title: "" } }).to render_template(:edit)
end
end
end
Now with the current user being saved Rspec throws me errors in create and update:
1) RecordsController#create creates a new record with the given title and description
Failure/Error: post :create, record: { title: title, description: description, user_id: user }
NoMethodError:
undefined method `authenticate' for nil:NilClass
# ./app/controllers/records_controller.rb:42:in `record_params'
# ./app/controllers/records_controller.rb:9:in `create'
# ./spec/controllers/records_controller_spec.rb:36:in `block (4 levels) in <top (required)>'
# ./spec/controllers/records_controller_spec.rb:35:in `block (3 levels) in <top (required)>'
# -e:1:in `<main>'
2) RecordsController#create fails to create a record and returns to the index page
Failure/Error: expect(post :create, record: { description: description }).to render_template(:index)
NoMethodError:
undefined method `authenticate' for nil:NilClass
# ./app/controllers/records_controller.rb:42:in `record_params'
# ./app/controllers/records_controller.rb:9:in `create'
# ./spec/controllers/records_controller_spec.rb:46:in `block (3 levels) in <top (required)>'
# -e:1:in `<main>'
3) RecordsController#update find the records and sets the new given values
Failure/Error: put :update, { id: record.id, record: { title: title, description: description } }
NoMethodError:
undefined method `authenticate' for nil:NilClass
# ./app/controllers/records_controller.rb:42:in `record_params'
# ./app/controllers/records_controller.rb:20:in `update'
# ./spec/controllers/records_controller_spec.rb:62:in `block (3 levels) in <top (required)>'
# -e:1:in `<main>'
4) RecordsController#update fails to create a record and returns to the edit page
Failure/Error: expect(put :update, { id: record.id, record: { title: "" } }).to render_template(:edit)
NoMethodError:
undefined method `authenticate' for nil:NilClass
# ./app/controllers/records_controller.rb:42:in `record_params'
# ./app/controllers/records_controller.rb:20:in `update'
# ./spec/controllers/records_controller_spec.rb:72:in `block (3 levels) in <top (required)>'
You need to login the user first before you can use the current_user.
Something like:
before do
sign_in :user, create(:user)
end
Also checkout How To: Test controllers with Rails 3 and 4 (and RSpec)
I was doing the RSpec testing with Rails and it's failing due to the namespaced model that I assigned to its associations of the model.
CLI:
Failures:
1) Blog::BlobsController GET index assigns all blog/blobs as #blobs
Failure/Error: expect(assigns(:blog::blobs)).to eq([blog::blobs])
NoMethodError:
undefined method `blobs' for :blog:Symbol
# ./spec/controllers/blog/blobs_controller_spec.rb:8:in `block (3 levels) in <top (required)>'
spec/controllers/blog/blobs_controller_spec.rb
RSpec.describe Blog::BlobsController, type: :controller do
describe "GET index" do
it "assigns all blog/blobs as #blobs" do
blobs = Blog::Blob.create!
get :index, {}
expect(assigns(:blog::blobs)).to eq([blog::blobs])
end
end
end
routes.rb
# SNIPPED FOR BREVITY...
namespace :blog do
resources :blobs
end
app/controllers/blog/blobs_controller.rb
class Blog::BlobsController < ApplicationController
before_filter :authenticate_user!, except: [:index, :show]
def index
#blobs = Blog::Blob.all
end
def new
#blob = Blog::Blob.new
end
def edit
#blob = Blog::Blob.find(params[:id])
end
def create
#blob = Blog::Blob.new(blob_params)
if #blob.save
redirect_to #blob
else
render 'new'
end
end
def update
#blob = Blog::Blob.find(params[:id])
if #blob.update(blob_params)
redirect_to #blob
else
render 'edit'
end
end
def show
#blob = Blog::Blob.find(params[:id])
end
def destroy
#blob = Blog::Blob.find(params[:id])
#blob.destroy!
redirect_to blog_blobs_path
end
private
def blob_params
params.require(:blob).permit(:title, :body)
end
end
Is there a better way to test this controller with RSpec?
UPDATE:
Failures:
1) Blog::BlobsController GET #index assigns all widgets as #widgets
Failure/Error: expect(assigns(:blobs)).to eq([blob])
TypeError:
no implicit conversion of Symbol into Integer
# /usr/local/rvm/gems/ruby-2.1.5#rails4/gems/mongo-2.0.4/lib/mongo/server_selector.rb:56:in `[]'
# /usr/local/rvm/gems/ruby-2.1.5#rails4/gems/mongo-2.0.4/lib/mongo/server_selector.rb:56:in `get'
# /usr/local/rvm/gems/ruby-2.1.5#rails4/gems/mongo-2.0.4/lib/mongo/client.rb:170:in `read_preference'
# /usr/local/rvm/gems/ruby-2.1.5#rails4/gems/mongo-2.0.4/lib/mongo/collection/view/readable.rb:318:in `default_read'
# /usr/local/rvm/gems/ruby-2.1.5#rails4/gems/mongo-2.0.4/lib/mongo/collection/view/readable.rb:251:in `read'
# /usr/local/rvm/gems/ruby-2.1.5#rails4/gems/mongo-2.0.4/lib/mongo/collection/view/iterable.rb:38:in `each'
# /usr/local/rvm/gems/ruby-2.1.5#rails4/bundler/gems/mongoid-26f67146a7b7/lib/mongoid/query_cache.rb:207:in `each'
# /usr/local/rvm/gems/ruby-2.1.5#rails4/bundler/gems/mongoid-26f67146a7b7/lib/mongoid/contextual/mongo.rb:116:in `each'
# /usr/local/rvm/gems/ruby-2.1.5#rails4/bundler/gems/mongoid-26f67146a7b7/lib/mongoid/contextual.rb:20:in `each'
# /usr/local/rvm/gems/ruby-2.1.5#rails4/bundler/gems/mongoid-26f67146a7b7/lib/mongoid/criteria.rb:48:in `entries'
# /usr/local/rvm/gems/ruby-2.1.5#rails4/bundler/gems/mongoid-26f67146a7b7/lib/mongoid/criteria.rb:48:in `=='
# ./spec/controllers/blog/blobs_controller_spec.rb:8:in `block (3 levels) in <top (required)>'
Updated spec code:
require 'rails_helper'
RSpec.describe Blog::BlobsController, type: :controller do
describe "GET #index" do
it "assigns all blobs as #blobs" do
blob = Blog::Blob.create!
get :index, {}
expect(assigns(:blobs)).to eq([blob])
end
end
end
Your test says:
blobs = Blog::Blob.create!
This is confusing, because blobs is plural, but you're only creating one blob. So start by renaming that to blob. Then expect(assigns(:blog::blobs)).to eq([blog::blobs]) should be expect(assigns(:blobs)).to eq([blob]).
In the index action, you set #blobs = Blog::Blob.all. The assigns correspond to the controller's instance variables. There's no namespacing.