Rails 4 model not found during rspec test - ruby-on-rails-4

I'm new to Rails, and I'm experiencing an odd phenomenon - a model seems to go missing during testing.
I have models for users and accounts, with a members model to show which users belong to which account:
account.rb
class Account < ActiveRecord::Base
belongs_to :admin, class_name: "User"
accepts_nested_attributes_for :admin
has_many :members
has_many :users, through: :members
has_many :clients
def self.create_with_admin(params={})
account = new(params)
if account.save
account.users << account.admin
end
account
end
end
user.rb
class User < ActiveRecord::Base
has_secure_password
belongs_to :members
end
member.rb
class Member < ActiveRecord::Base
belongs_to :account
belongs_to :user
end
During the test, the following function located in the application_controller is run to return the account object associated with the users account (updated per comments):
1 def current_account
2 if user_signed_in?
3 #current_account ||= begin
4 user = env["warden"].user.id
5 member = Member.find_by user_id: user
6 Account.find member.account_id
7 end
8 end
9 end
log
Processing by Account::DashboardController#index as HTML # this is the controller processing the 'current_account' function
"[ApplicationController.current_account] user: 65"
Member Load (0.4ms) SELECT "members".* FROM "members" WHERE "members"."user_id" = $1 LIMIT 1 [["user_id", 65]]
Completed 500 Internal Server Error in 2ms (ActiveRecord: 0.4ms)
(0.3ms) ROLLBACK
Though warden authentication succeeds (i.e., env["warden"].user.id returns the currently signed in user's id), the function fails at line 5 with a "NoMethodError: undefined method for nil:nilClass". It would seem to me that the Member class is not being found, or that find_by is not a valid method for the model(?).
Is there an explanation for this situation, and what can I do to correct the issue?

Related

ActiveRecord::UnknownAttributeError: unknown attribute 'article_id' for Tagging

I am work on a Blogger Rails App from section I3 :
http://tutorials.jumpstartlab.com/projects/blogger.html#blogger-2
I am getting an error when running the console and attempting to run:
a.tags.create name: "tag1"
After I run:
a = Article.first
tagging.rb file:
class Tagging < ActiveRecord::Base
belongs_to :tag
belongs_to :articles
end
article.rb file:
class Article < ActiveRecord::Base
has_many :comments
has_many :taggings
has_many :tags, through: :taggings
end
tag.rb file:
class Tag < ActiveRecord::Base
has_many :taggings
has_many :articles, through: :taggings
end
I tried adding has_many :article_id to the tagging class, raked the db:migration and ran it again and it came back with a no method for nill class error.
Where should I define the article_id? Does it need to go in to migration file for CreateTagging?
The tagging.rb file is your join file, and you have article_id and tag_id defined in there.
I note that you have belongs_to :articles ... you should be using the singular ... belongs_to :article. That's likely why you're failing. Provided you did...
generate model Tagging tag:references article:references
... as the tutorial suggests, that would have automatically created the two id fields for you in the taggings table.
You can confirm that by examining the db/schema.rb

Rails 4 has_one through with where clause

I am trying to establish a direct relation via has_one between two models, Client and Address as in has_one :billing_address but Client doesn't have a direct relation to Address, Contact does, the models:
Client
class Client < ActiveRecord::Base
belongs_to :contact
accepts_nested_attributes_for :contact
end
Contact
class Contact < ActiveRecord::Base
has_one :client
has_many :addresses, dependent: :destroy
accepts_nested_attributes_for :addresses, allow_destroy: true
end
Address
class Address < ActiveRecord::Base
belongs_to :contact
enum kind: [:address, :shipping, :billing]
end
So what I want is to to be able to do Client.shipping_address or Client.billing_address, the enum in the Address model is what will allow the query. The reason behind that is because the Contact of Client will have two address records, one for billing and one for shipping and I want quick access via relations
I tried in the Client model:
has_one(:billing_address, -> { where(kind: :billing) }, class_name: Address, through: :contact)
But when in the view I o:
client.billing_address
I get a undefined method to_sym' for nil:NilClass And I can't seem to resolve it, thanks.
You need to specify the :source on the association since it cannot be inferred.
has_one :billing_address, through :contact, source: :addresses, -> { where(kind: :billing) }
Without :source, it's going to look for a :billing_address association on the Contact model.
Source
Update
After reading up on the enum docs, it looks like you may need to modify the scope, referencing the mapping directly:
-> { where(kind: Address.kinds[:billing]) }
I believe this is because the :kind field in the database is expected to be type INTEGER.

building nested resources for a form

I have a class User which has sub classes IndividualUser and BusinessUser (through STI). IndividualUser and BusinessUser have a many-to-many association and are linked through a join table called Employees.
Also, a User can have an Account.
I'm trying to set up a nested form, and am struggling to create the required objects.
My models:
class User
has_one :account
end
class IndividualUser < User
has_many :business_users, :through => :employees
has_many :employees
end
class BusinessUser < User
has_many :individual_users, :through => :employees
has_many :employees
end
class Employee < ActiveRecord::Base
belongs_to :business_user
belongs_to :individual_user
end
class Account
belongs_to :user
end
Now, in my controller, I am able to create a new account for an individual user:
# GET /individual_users/new
def new
#individual_user = IndividualUser.new
#individual_user.build_account
end
This works fine.
However, when I try to create a business_user, then individual_users, and then an account for each individual_user:
# GET /business_users/new
def new
#business_user = BusinessUser.new
#business_user.employees.build()
#business_user.employees.each do |employee|
#individual_user = employee.build_individual_user
#individual_user.build_account
end
end
I get the following error:
undefined method `build_account' for nil:NilClass
It appears as though #individual_user is not being created.
I'm not sure why I'm getting this error. Any ideas?
What's really strange, is that if I instead move the code to the view, it appears to work. i.e. in my view:
<% #business_user.employees.each do |employee| %>
<% employee.individual_user.build_scoot_account %>
<% employee.individual_user.scoot_account.id = 2 %>
<%= employee.individual_user.scoot_account.id %>
<% end %>
This displays "2".

Add items to a has_many relation on creation

I'm trying to make a has_many relation work for object to be created.
It is a simple case and despite many efforts and researches through the web, I cannot find why my code is not working.
I have the following classes (note: some variables use French names):
class Comptes::Category < ActiveRecord::Base
has_many :categorizations, dependent: :destroy
accepts_nested_attributes_for :categorizations
has_many :transactions, through: :categorizations
validates :nom, presence: true, uniqueness: true
end
class Comptes::Transaction < ActiveRecord::Base
has_many :categorizations, dependent: :destroy
accepts_nested_attributes_for :categorizations
has_many :categories, through: :categorizations
... # some validations
end
class Comptes::Categorization < ActiveRecord::Base
belongs_to :transaction
belongs_to :category
validates :transaction, presence: true
validates :category, presence: true
end
Category and Transaction are the basic models and Categorization is dedicated to the association (this is a basic account - transaction system).
What I can do is create a transaction and a category then fill transaction.categories with the category (transaction has thus an id).
What I cannot do is:
transaction = Comptes::Transaction.new ...
category = Comptes::Category.first
transaction.categories << category
# OR
transaction.categorizations.build category: category
# OR
# use categorizations_attributes in and accepts_nested_attributes_for.
Thank you very much for any help
Edit: this is done in rails 4.0.0
And I found that the issue was coming from the validation in Comptes::Categorization.
This prevents creation of new categorizations if the transaction or category does not exist yet.
Update (18/08/2014): the issue is coming from the validation in Categorizations, which prevent from creating the association without existing transaction and category. This may be an issue in rails 4.0.0. To see...
Transaction class is not under the module Comptes. Therefore, when you do has_many :categorizations or has_many :categories in it, the corresponding models are inferred as Categorization and Category instead of Comptes::Categorization and Comptes::Category.
To resolve this, you need to specify the class_name option of the association because the name of the model can't be inferred from the association name.
Update the class Transaction as below:
class Transaction < ActiveRecord::Base
has_many :categorizations, class_name: "Comptes::Categorization" , dependent: :destroy
accepts_nested_attributes_for :categorizations
has_many :categories, through: :categorizations, class_name: "Comptes::Category"
end

displaying the user that owns the notification in rails

i got an application that includes Activities, Users, Talks and Notifications. the model include
Users Model
has_many :talks, :dependent => :destroy
has_many :notifications, :dependent => :destroy
has_many :activities, :dependent => :destroy
Notifications Model
has_many :users, -> {uniq}, through: :talks
belongs_to :user
belongs_to :trackable, polymorphic: true
has_many :talks
has_many :notifications
When creating a talk i do this
def create
#activity = Activity.find(params[:activity_id])
#talk = #activity.talks.create!(talk_params)
#talk.user = current_user
#talk.save
##users= #activity.users.where("id NOT IN (?)", [#activity.user.id, #talk.user])
#users= User.joins(:talks).where(talks: {id: #activity.talk_ids}).push(#activity.user).reject {|user| user == #talk.user }.uniq
## Lets create a notification for all those who created a comment in this activity
#users.each do |user|
Notification.create(activity:#activity, user: user)
end
## Lets create a notification for the owner activity
#Notification.create(activity:#activity, user: #activity.user)
redirect_to user_path(current_user)
end
and with this a notification is created what i want is to display the name of the owner of the notification .. i dont know how to go about that
Try this code:
#users.each do |user|
noti = Notification.create(activity:#activity, user: user)
notifications = #activity.user.notifications
notifications << noti
#activity.user.update(notifications:, notifications)
end
If each notification has creator(:user), receiver(:user), so you need to have two columns for Notification model (sender_id, recipient_id).
Facebook Notification
You need read about inheritance from single table(User)
Inheritance from single table(1)
Inheritance from single table(2)