displaying the user that owns the notification in rails - ruby-on-rails-4

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)

Related

Can a model have two associations to the same model, using :through?

Let's say I have three models: Organization, Skills and Assessments.
Can an Assessment belong to two different Organizations, via different relations?
For example, an assessment may have happened at organization A, but was based on a skill belonging to organization B.
Below are my models and associations:
class Organization < ActiveRecord::Base
has_many :checklists
has_many :levels, :through => :checklists
has_many :sections, :through => :levels
has_many :skills, :through => :sections
has_many :assessments_using_own_checklists, :through => :skills, :source => :assessments
end
class Skill < ActiveRecord::Base
belongs_to :section
has_one :level, through: :section
has_one :checklist, through: :level
has_one :organization, through: :checklist
has_many :assessments
end
class Assessment < ActiveRecord::Base
belongs_to :skill
has_one :section, through: :skill
has_one :level, through: :section
has_one :checklist, through: :level
has_one :checklist_owner, through: :checklist, source: :organization
belongs_to :organization
end
Using the above, I can get an assessment's organization:
Assessment.last.organization # yields organization 1
I can also get an assessment's checklist_owner:
Assessment.last.checklist_owner # yields organization 2
But when I try to use checklist_owner in a where, the association seems to forget to use the :through. For example, if I run:
Assessment.where(organization: Organization.find(2), checklist_owner: Organization.find(1))
... this translates to SQL:
SELECT "assessments".* FROM "assessments" WHERE "assessments"."organization_id" = 2 AND "assessments"."organization_id" = 1
See how the SQL has two "assessments"."organization_id" = statements? Why does it do that?
Have you tried using joins?
something like:
Assessment.joins(skill: { section: { level: :checklist } }).where(organization: Organization.find(2), checklists: { organization_id: Organization.find(1) })
I know it look bad, but it seems that your relation from assessment to checklist is very complicated. This would take care of any weird relations being made.

UnknownAttributeError for nested form

I have two model as:
Customer:
has_many :products, :dependent => :destroy
accepts_nested_attributes_for :products, reject_if: proc { |attributes| attributes['product_id'].blank? }
Product:
belongs_to :customer
products controller:
def product_params
params.require(:product).permit(:name, :first_build)
end
customers controller:
def customer_params
params.require(:customer).permit(:first_build, :name, :product_id,
products_attributes: [:first_build, :customer_id])
end
So in the customers controller I do this
#customer.products.build(:first_build => true)
but I get this error
unknown attribute 'first_build' for Prodcut
but when I do this #customer.products.build(:name => "test product name")
it works perfectly without any error. One thing to note here, first_build is not a column in the products table.
If you want to pass attributes that are not in the table, you can create a "temporary" attribute which will not be stored in the table but will be available while the object is in memory.
class Product < ActiveRecord::Base
attr_accessor :first_build
...
end

Re-named associations working correctly

I have two types of users, one that can create movies and one that can create reviews:
class User < ActiveRecord::Base
has_many :created_movies, foreign_key: 'creator_id', class_name: 'Movie'
has_many :reviewed_movies, foreign_key: 'reviewer_id', :through => 'Review'
end
class Review < ActiveRecord::Base
belongs_to :movie
belongs_to :reviewer, class_name: 'User'
end
class Movie < ActiveRecord::Base
has_many :reviews
belongs_to :creator, class_name: 'User'
end
Whenever I try to run the following in my users/show:
<% if #user.reviewed_movies.any? %>
I get this problem:
ActiveRecord::HasManyThroughAssociationNotFoundError at /users/1
Could not find the association "Review" in model User
I can see that I can successfully populate the reviewer_id with the correct user when the review is created when I go into the command line:
m = Movie.last
m.reviews[1]
# => <Review:0x007fdc4036a938> {
# :id => 2,
# :rating => 2,
# :title => "bye",
# :content => "byeeeee",
# :created_at => Tue, 15 Sep 2015 19:20:25 UTC +00:00,
# :updated_at => Tue, 15 Sep 2015 19:20:25 UTC +00:00,
# :movie_id => 3,
# :reviewer_id => 1
# }
But I can't retrieve it from the other end. If anyone can provide some assistance it would be greatly appreciated, thanks!
ActiveRecord::HasManyThroughAssociationNotFoundError at /users/1 Could
not find the association "Review" in model User
The problem is here in this line
has_many :reviewed_movies, foreign_key: 'reviewer_id', :through => 'Review'
Which should be
has_many :reviewed_movies, foreign_key: 'reviewer_id', class_name: 'Review'
You need to tell your User model it has many reviews through which it has many movies called "reviewed_movies".
class User < ActiveRecord::Base
has_many :created_movies,
foreign_key: :movie_id,
class_name: 'Movie'
has_many :reviews
has_many :reviewed_movies,
foreign_key: :movie_id,
through: :reviews,
class_name: 'Movie'
end
EDIT: The foreign key is there to tell your model which foreign key to use, if your relation isn't called the same as the foreign-key, so I think it should be 'movie_id'... Ok, not sure about this any longer, I guess it depends on your setup ^^

Rails 4 model not found during rspec test

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?

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.