require 'rails_helper'
feature "comment" do
given(:current_user) do
create(:user)
end
given(:undertaking) do
create(:undertaking)
end
background do
login_as(current_user)
end
scenario "can create comment" do
#below two because undertaking = user_id:2 & asking_id:1
create(:user)
create(:asking)
p undertaking
p Asking.find(1)
p User.find(2)
p User.find(1)
p Undertaking.all
visit undertaking_path(undertaking)
expect(current_path).to eq undertaking_path(1)
within("form#undertake-form-test") do
fill_in "content" , with: "heyheyhey"
end
click_button 'Send'
expect(page).to have_content 'heyheyhey'
end
end
This is spec/features/comment_spec.rb.
and this below is result command rspec.
#<Undertaking id: 1, title: "MyString", content: "MyText", result: false, user_id: 2, asking_id: 1, created_at: "2016-12-13 15:07:08", updated_at: "2016-12-13 15:07:08">
#<Asking id: 1, content: "MyText", fromlang: "MyString", tolang: "MyString", usepoint: 1, finished: false, title: "MyString", deadline: nil, user_id: 1, created_at: "2016-12-13 15:07:08", updated_at: "2016-12-13 15:07:08">
#<User id: 2, email: "shiba.hayato2#docomo.ne.jp", created_at: "2016-12-13 15:07:08", updated_at: "2016-12-13 15:07:08", provider: nil, uid: nil, name: "Shiruba", occupation: "大学生", age: 10, sex: "男性", content: "heyheyheyeheyeheye", skill: "日本語検定3級", picture: "/assets/default_user.jpg", point: 500, country: "Japan", language1: "Japanese", language2: "Korea", language3: "English">
#<User id: 1, email: "shiba.hayato1#docomo.ne.jp", created_at: "2016-12-13 15:07:08", updated_at: "2016-12-13 15:07:08", provider: nil, uid: nil, name: "Shiruba", occupation: "大学生", age: 10, sex: "男性", content: "heyheyheyeheyeheye", skill: "日本語検定3級", picture: "/assets/default_user.jpg", point: 500, country: "Japan", language1: "Japanese", language2: "Korea", language3: "English">
#<ActiveRecord::Relation [#<Undertaking id: 1, title: "MyString", content: "MyText", result: false, user_id: 2, asking_id: 1, created_at: "2016-12-13 15:07:08", updated_at: "2016-12-13 15:07:08">]>
F
Failures:
1) comment can create comment
Failure/Error: <%= #undertaking.id %>
ActionView::Template::Error:
undefined method `id' for nil:NilClass
and this below is undertaking_controller.rb.
class UndertakingController < ApplicationController
def show
#undertaking=Undertaking.find(params[:id])
#comment=Comment.new do |c|
c.user=current_user
end
end
end
and this below is undertaking/show.html.erb.
<%= #undertaking.id %>
Why do I have the error? Why #undertaking is nil in view although Undertaking.first is not nil in spec/features/comment_spec.rb?Please help me.
I think it has to do with the naming used for your controller . The convention is undertakings/show.html.erb for the view instead of undertaking/show.html.erb . I would also use
class UndertakingsController < ApplicationController
instead of
class UndertakingController < ApplicationController
Finally I would check that all my routes also have the correct naming. Hope that helps. Good luck
Related
I'm not very sure I'm doing it right, but I have two models: House that has_one Address.
The Address model has:
class Address < ApplicationRecord
searchkick
belongs_to :house
end
I'm trying to test my house_controller with RSpec like this
RSpec.describe HousesController do
context 'GET #index' do
before { get :index }
it { is_expected.to render_template('index') }
it 'assigns #houses' do
h = create(:house)
expect(assigns(:houses).results).to eq([h])
end
...
Nevertheless I always get a result which is not the one I expect.
The code of my controller is the following:
def index
if params[:term].present?
#houses = House.search(params[:term])
else
#houses = House.search('*')
end
end
I'm not sure I understand it, but could it be that since I'm using FactoryBot, it is creating lots of houses, and then when getting in the index method, there's a bunch of houses there and not only and precisely h?
This is my failure:
Failures:
1) HousesController GET #index assigns #houses
Failure/Error: expect(assigns(:houses).results).to eq([h])
expected: [#<House id: 763, rent: 1173, deposit: 739, description: "Rerum cado curso curo alias.", preferred_ge...2018-11-26 21:40:43", available_at: "2018-12-17", user_id: 15945, lease_length: nil, built_in: nil>]
got: [#<House id: 215, rent: 0.839e3, deposit: 0.797e3, description: "Rerum aeneus taceo crepusculum aestu...2018-11-26 21:17:53", available_at: "2018-12-17", user_id: 15776, lease_length: nil, built_in: nil>]
(compared using ==)
Diff:
## -1,2 +1,5 ##
-[#<House id: 763, rent: 1173, deposit: 739, description: "Rerum cado curso curo alias.", preferred_gender: 0, created_at: "2018-11-26 21:40:43", updated_at: "2018-11-26 21:40:43", available_at: "2018-12-17", user_id: 15945, lease_length: nil, built_in: nil>]
+[#<House id: 215, rent: 0.839e3, deposit: 0.797e3, description: "Rerum aeneus taceo crepusculum aestus.", preferred_gender: 0, created_at: "2018-11-25 12:50:11", updated_at: "2018-11-25 12:50:11", available_at: "2018-12-16", user_id: 8065, lease_length: nil, built_in: nil>,
+ #<House id: 235, rent: 0.519e3, deposit: 0.642e3, description: "Cicuta totidem arbustum arcesso fugit tego.", preferred_gender: 0, created_at: "2018-11-25 12:54:28", updated_at: "2018-11-25 12:54:28", available_at: "2018-12-16", user_id: 8085, lease_length: nil, built_in: nil>,
+ #<House id: 648, rent: 0.668e3, deposit: 0.1104e4, description: "Corporis tametsi demens.", preferred_gender: 0, created_at: "2018-11-26 21:17:43", updated_at: "2018-11-26 21:17:43", available_at: "2018-12-17", user_id: 15775, lease_length: nil, built_in: nil>,
+ #<House id: 649, rent: 0.799e3, deposit: 0.611e3, description: "Ut ancilla tredecim.", preferred_gender: 0, created_at: "2018-11-26 21:17:53", updated_at: "2018-11-26 21:17:53", available_at: "2018-12-17", user_id: 15776, lease_length: nil, built_in: nil>]
# ./spec/controllers/houses_controller_spec.rb:12:in `block (3 levels) in <top (required)>'
I'm starting with RSpec now and it's really taking me effort and hours to try to grab the grasp of it, thanks a lot in advance!
Searchkick docs about disabling indexing for tests with RSpec.
You don't want to be updating your objects in Elasticsearch always while running tests. You want to do it only when you'll be explicitly testing your search functionality (or indexing/deleting from index). To do so, you will have to disable searchkick callbacks, define a custom tag for your tests and enable indexing only for these tests. You may have to handle cleaning your index after a test/groups of tests as well.
#vich's point is also important, you currently create your object too late, after the request.
I would change your setup to:
context 'GET #index', :search do
let!(:house) { create(:house) }
before { get :index }
it 'assigns #houses' do
expect(assigns(:houses).results).to eq([house])
end
end
Try creating your house in the before block:
context 'GET #index' do
before do
let!(:house) { create(:house) }
get :index
end
it { is_expected.to render_template('index') }
it 'assigns #houses' do
expect(assigns(:houses).results).to eq([house])
end
end
A couple of things to note:
As opposed to let, let! is immediately invoked (thus creating your record before the index action is hit)
Add a breakpoint (IDE) or use a debugger (byebug, pry, etc.) and put it before the get :index call to see what (if any) houses already exist.
I am trying to test the following controller action(Using Ruby on Rails, RSPEC, and FactoryGirl):
class ContactsController < ApplicationController
before_action :authenticate_user!
def index
#contacts = current_user.contacts
# #contacts = Contact.all
end
Here is my contacts_controller_spec.rb file:
require 'rails_helper'
describe ContactsController do
before do
#user = FactoryGirl.create(:user_with_contacts)
sign_in #user
end
describe "GET INDEX" do
it "assigns #contacts" do
expect(assigns(:contacts)).to eq(#user.contacts)
end
end
Failure/Error: expect(assigns(:contact)).to eq([contact])
expected: [#<Contact id: 295, first_name: "Loy", email: "leon#hegmannhintz.net", phone_number: "6044339393", created_at: "2015-09-12 19:13:42", updated_at: "2015-09-12 19:13:42", last_name: "Wyman", user_id: 343>]
got: #<Contact id: nil, first_name: nil, email: nil, phone_number: nil, created_at: nil, updated_at: nil, last_name: nil, user_id: nil>
And here is my users_spec.rb file:
FactoryGirl.define do
factory :user do
email { Faker::Internet.email }
password { "32423fdsfasf42" }
factory :user_with_contacts do
transient do
contacts_count 2
end
after(:create) do |user, evaluator|
create_list(:contact, evaluator.contacts_count, user: user)
end
end
end
end
Any Help please? I have been stuck on this for a long time.
If i call
puts #user.inspect
I get
#<User id: 340, email: "johnson_kaulke#brekke.com", encrypted_password: "$2a$04$Si5k6Q1eYERvhQITXKBoIOGEzPyK50E3IQ.yjRcqmDj...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: "2015-09-12 19:13:42", updated_at: "2015-09-12 19:13:42">
and
calling
puts #user.contacts.inspect
I get
#<ActiveRecord::Associations::CollectionProxy [#<Contact id: 289, first_name: "Fae", email: "ariane#johnston.net", phone_number: "6044339393", created_at: "2015-09-12 19:13:42", updated_at: "2015-09-12 19:13:42", last_name: "Spinka", user_id: 340>, #<Contact id: 290, first_name: "Marcellus", email: "chloe_deckow#buckridge.net", phone_number: "6044339393", created_at: "2015-09-12 19:13:42", updated_at: "2015-09-12 19:13:42", last_name: "Bashirian", user_id: 340>]>
Its just when i call the assigns(:contacts) that the problem happens!
I think you forgot to invoke the controller action. :)
Try adding get :index
it "assigns #contacts" do
get :index
expect(assigns(:contacts)).to eq(#user.contacts)
end
When I comment out my after_save call back, my ActiveRecord associations work just fine. In Rails Console, you'd see:
> #report = Report.create :name => "foo"
=> #<Report id: 9, name: "foo", created_at: "2013-03-05 09:51:55", updated_at: "2013-03-05 09:51:55">
> #question = #report.questions.create :description => "bar"
=> #<Question id: 18, standard_id: nil, description: "bar", element_id: nil, condition_id: nil, blueprint_name: nil, blueprint_url: nil, created_at: "2013-03-05 09:52:32", updated_at: "2013-03-05 09:52:32", additive: false, instructions: nil>
> #report.questions
=> [#<Question id: 18, standard_id: nil, description: "bar", element_id: nil, condition_id: nil, blueprint_name: nil, blueprint_url: nil, created_at: "2013-03-05 09:52:32", updated_at: "2013-03-05 09:52:32", additive: false, instructions: nil>]
> #question.reports
=> [#<Report id: 9, name: "foo", created_at: "2013-03-05 09:51:55", updated_at: "2013-03-05 09:51:55">]
However, the associations stop working when I add the following after_save callback to question.rb:
def create_matching_surveys
self.reports.each do |report|
report.reviews.each do |review|
review.competitors.each do |competitor|
competitor.surveys.find_or_create_by_question_id(self.id)
end
end
end
end
Then, in Rails Console, you get:
> #report = Report.create :name => "foo"
=> #<Report id: 13, name: "foo", created_at: "2013-03-05 10:20:51", updated_at: "2013-03-05 10:20:51">
> #question = #report.questions.create :description => "bar"
=> #<Question id: 24, standard_id: nil, description: "bar", element_id: nil, condition_id: nil, blueprint_name: nil, blueprint_url: nil, created_at: "2013-03-05 10:21:02", updated_at: "2013-03-05 10:21:02", additive: false, instructions: nil>
> #report.questions
=> [#<Question id: 24, standard_id: nil, description: "bar", element_id: nil, condition_id: nil, blueprint_name: nil, blueprint_url: nil, created_at: "2013-03-05 10:21:02", updated_at: "2013-03-05 10:21:02", additive: false, instructions: nil>]
> #question.reports
=> []
This happens whether or not the report has reviews that have competitors.
The strange thing is I thought the callback was meant to happen after the question was saved? So by rights the association should save too before any of this happens, right?
How do I fix it?
UPDATE
I think I have to call the callback in the right spot in the object's life cycle, but I can't find that spot. Here's why I think this:
> #report = Report.create :name => "foo"
=> #<Report id: 20, name: "foo", created_at: "2013-03-05 12:29:35", updated_at: "2013-03-05 12:29:35">
> #question = #report.questions.create :description => "bar"
=> #<Question id: 31, standard_id: nil, description: "bar", element_id: nil, condition_id: nil, blueprint_name: nil, blueprint_url: nil, created_at: "2013-03-05 12:30:14", updated_at: "2013-03-05 12:30:14", additive: false, instructions: nil>
> #question.reports
=> []
> #question.update_attributes :description => "foo"
=> true
> #question.reports
=> [#<Report id: 20, name: "foo", created_at: "2013-03-05 12:29:35", updated_at: "2013-03-05 12:29:35">]
BTW, the method is now in question_observer.rb:
class QuestionObserver < ActiveRecord::Observer
def after_save(model)
model.reload
model.reports.reload
model.reports.each do |report|
report.reviews.each do |review|
review.competitors.each do |competitor|
competitor.surveys.find_or_create_by_question_id(model.id)
end
end
end
return true
end
end
The answer was to use a neat new callback hook called after_commit which was introduced with Rails 3.
See http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html#method-i-after_commit.
The only issue is after_commit doesn't work "out of the box" with transactional fixtures, but there are plenty of solutions out there, and I found this one worked well for me: https://supportbee.com/devblog/2012/01/14/testing-after_commitafter_transaction-with-rspec/
I am only familiar with Rspec, but now I need to fix a library which uses Test::Unit.
I find out that when I reload the record, the association becomes nil
For example:
test "accepts nested attributes from subscription to user ()" do
#user = User.create(name:'Ash')
#subscription = #user.create_subscription()
puts "user: " << #user.inspect
puts "subscription: " << #user.subscription.inspect
#subscription.update_attributes({ :user_attributes => { :notification_comment => true } })
#user.reload
puts "user: " << #user.inspect
puts "subscription: " << #user.subscription.inspect
assert #user.subscription, "should have an subscription"
end
Outputs:
user: #<User id: 815823837, account_id: nil, name: "Ash", email: nil, settings: {}, created_at: "2013-02-07 04:28:51", updated_at: "2013-02-07 04:28:51">
subscription: #<Subscription id: 1, user_id: 815823837, created_at: "2013-02-07 04:28:51", updated_at: "2013-02-07 04:28:51">
user: #<User id: 815823837, account_id: nil, name: "Ash", email: nil, settings: {}, created_at: "2013-02-07 04:28:51", updated_at: "2013-02-07 04:28:51">
subscription: nil
Why does this happen? I did check and I can confirm that I can Subscription.find(#subscription.id) so it is saved in the database.
Now in my application.html.erb in views folder, I wrote this.
<p>List of all post IDs: <%= Post.all.each {|i| print i.id } %></p>
I would like it to output just the post.id of each post. But instead it shows this
List of all post IDs: [#<Post id: 1, title: "Our First Post", content: "Content for our first post", created_at: "2012-11-24 11:22:02", updated_at: "2012-11-26 17:40:54", user_id: 1>, #<Post id: 3, title: "Our Second Post", content: "Content for our second post", created_at: "2012-11-24 11:51:32", updated_at: "2012-11-26 17:41:33", user_id: 2>, #<Post id: 8, title: "Our Second Post", content: "Content of Our mandatory Second Post", created_at: "2012-11-24 19:42:02", updated_at: "2012-11-27 20:46:57", user_id: 1>, #<Post id: 10, title: "C Post", content: "Hi I'm Cee nice to meet you", created_at: "2012-11-26 17:51:20", updated_at: "2012-11-26 17:51:20", user_id: 3>, #<Post id: 20, title: "11", content: "11", created_at: "2012-11-27 19:58:48", updated_at: "2012-11-27 19:58:48", user_id: 4>, #<Post id: 21, title: "22", content: "22", created_at: "2012-11-27 19:58:53", updated_at: "2012-11-27 19:58:53", user_id: 4>, #<Post id: 25, title: "I'm Super Singha!", content: "Yessar!!!", created_at: "2012-11-27 20:45:07", updated_at: "2012-11-27 20:45:07", user_id: 6>, #<Post id: 26, title: "Should this be a blog or a forums or a whatever-wha...", content: ";asljdfi;asfi;asdf;lasbfurbofioboboeifhosdsdbvisbvw...", created_at: "2012-11-27 20:46:28", updated_at: "2012-12-02 14:17:14", user_id: 1>, #<Post id: 27, title: "Hullow", content: "Yoyoyo", created_at: "2012-11-30 07:35:38", updated_at: "2012-11-30 07:35:54", user_id: 6>, #<Post id: 649, title: "um", content: "hey", created_at: "2012-11-30 12:20:58", updated_at: "2012-11-30 12:20:58", user_id: 2>, #<Post id: 82692, title: "LALALALAL", content: "hiopsdahfiosadhfioahfio", created_at: "2012-12-02 13:59:04", updated_at: "2012-12-02 14:22:41", user_id: 2>, #<Post id: 82693, title: "ggg", content: "fff", created_at: "2012-12-02 14:29:42", updated_at: "2012-12-02 14:29:42", user_id: 2>, #<Post id: 82694, title: "sick", content: "sick", created_at: "2012-12-02 14:41:32", updated_at: "2012-12-02 14:41:32", user_id: 5>]
I have tried, puts instead of print, that doesn't work either.
Further: I would also like to make a link_to each post show page from the intended result, how can I achieve that?
Here's my repo: https://github.com/nixor/cpblog , here's heroku site: http://still-plains-5469.herokuapp.com/
Thanks.
The problem is with how you are using the ERB tags here:
<%= Post.all.each {|i| print i.id } %>
Whenever you use <%=, the result of the block will be rendered. In your case, Post.all.each {} returns an array object, which is exactly what you are seeing in your rendered HTML.
In order to print out each item, you will need to loop through the items using <% and then print out what you want using <%=.
<p>List of all post IDs:
<% Post.all.each |post| do %>
<%= link_to post.id, post_path(post) %>
<% end %>
</p>
<p>List of all post IDs:
</p>
<%= Post.all.each do |e| %>
<p>
<%= e.Id %>
<p>
<%= link_to "Show", e %>
<% end %>