Re-named associations working correctly - ruby-on-rails-4

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 ^^

Related

Nested form has_many through issue

I have two models which are related with has_many :through association.
I have user & software_license models associated through user_software_license model. I am trying to save data using nested form, but I am getting errors
my models :
user.rb
has_many :software_licenses, through: :user_software_licenses
has_many :user_software_licenses
accepts_nested_attributes_for :software_licenses, :allow_destroy => true
software_license.rb
has_many :users, through: :user_software_licenses
has_many :user_software_licenses
accepts_nested_attributes_for :user_software_licenses
user_software_license.rb
belongs_to :user
belongs_to :software_license
my nested form :
= f.fields_for :software_licenses do |software_license|
= render :partial => "users/software_licenses", :locals => {:f => software_license}
= link_to_add_fields "Add", f, :user_software_licenses, true, "users/software_licenses"
this is how I am initialising it in my controller
user.software_licenses.build
and when I click on 'add more' button in nested form after submitting form I am getting parameters like this :
"software_licenses_attributes"=>{"0"=>{"id"=>"2"}},
"user_software_licenses"=>{"id"=>"2"},

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.

(rails4)how can i validate an user cannot book a route with overlapping time?

i have an user model:
class User < ActiveRecord::Base
has_secure_password
attr_accessible :email, :password, :password_confirmation, :cardnumber, :registration
validates_uniqueness_of :email
has_many :bookings
has_many :routes, :through => :bookings
end
then a route model :
class Route < ActiveRecord::Base
attr_accessible :id, :departurecity, :arrivalcity, :departuretime, :arrivaltime, :train_id
has_many :stops
belongs_to :train
has_many :bookings
has_many :users, :through => :bookings
end
an finally bookink model:
class Booking < ActiveRecord::Base
attr_accessible :route_id, :user_id, :dateb, :hourb, :citydeparture, :cityarrival, :id, :tripclass
belongs_to :user
belongs_to :route
The question is how can I make a method on booking model which an user cannot book a train route with overlap time on another booked train route by the same user?

ActiveAdmin has_many through relationship not updating param Rails

I'm working through creating a has_many: through relationship in active admin. Here are the models as they stand:
class Category < ActiveRecord::Base
has_many :subcategories
end
class Subcategory < ActiveRecord::Base
has_many :product_in_subcategories
has_many :products, through: :product_in_subcategories
accepts_nested_attributes_for :product_in_subcategories, :allow_destroy => true
belongs_to :category
end
class Product < ActiveRecord::Base
has_many :product_in_subcategories
has_many :subcategories, through: :product_in_subcategories
accepts_nested_attributes_for :product_in_subcategories, :allow_destroy => true
end
class ProductInSubcategory < ActiveRecord::Base
belongs_to :product
belongs_to :subcategory
end
In ActiveAdmin I have the permit_params and form like so:
ActiveAdmin.register Product do
# note some params that are product only have been removed for simplicity
permit_params :name, subcategory_id:[:id], product_in_subcategories_attributes: [:id, :subcategory_id, :product_id, :_create, :_update]
form do |f|
f.inputs
f.has_many :product_in_subcategories do |s|
s.input :subcategory_id, :as => :check_boxes, :collection => Subcategory.all
end
f.actions
end
end
The form populates as should, and will save everything except for the subcategory_id. If I enter into the DB a proper subcategory_id the box will show checked on edit.
The messages when saving give:
Unpermitted parameters: subcategory_id
However, it appears it is trying to submit this with the product, for which there isn't a subcategory_id. Any ideas on what I am doing incorrectly here? This is driving me nuts and I've read everything I can find. I'd really like to understand what I'm doing wrong. Thanks.
After much time spent on this one, I couldn't find a suitable solution except for this one, which is actually very nice. It in fact is not much different from my envisioned solution:
The only changes to the above code were made in ActiveAdmin:
ActiveAdmin.register Product do
# note some params that are product only have been removed for simplicity
permit_params :name, product_in_subcategories_attributes: [:id, :subcategory_id, :product_id, :_create, :_update]
form do |f|
f.inputs
f.has_many :product_in_subcategories do |s|
s.input :subcategory_id, :as => :select, :collection => Subcategory.all
end
f.actions
end
end
Very strange how this allows a select box with no issues, but it flips out over check boxes. Nonetheless, I'm happy with the solution.

Rails 4 has many through

Hi there I'm a rails newbie and am having a hard time understanding an error I am getting.
I have many to many relationship that consists of
Project -> one to many project_numbers (billing numbers)
project_number -> has id, project_id(fk), task_name and hours associated with a task.
Associate-> Employee/Developer performing work (id, name, ...)
Resource -> Join table containing ID, project_number_id (fk) and Associate_id (fk), hrs assigned, hours used
My Model is as follows
#project.rb
class Project < ActiveRecord::Base
database_connection = Rails.env
establish_connection database_connection.to_sym
self.table_name = 'projects'
belongs_to :client, :inverse_of => :project
has_many :project_numbers
end
#associate.rb
class Associate < ActiveRecord::Base
database_connection = Rails.env
establish_connection database_connection.to_sym
self.table_name = 'associates'
has_many :resources
#has_many :project_numbers, through: => :resources
end
#project_number.rb
class ProjectNumber < ActiveRecord::Base
database_connection = Rails.env
establish_connection database_connection.to_sym
self.table_name = 'project_numbers'
belongs_to :project, :inverse_of => :project_number
has_many :resources
#has_many :associates, through: => :resources
end
resource.rb
class Resource < ActiveRecord::Base
database_connection = Rails.env
establish_connection database_connection.to_sym
self.table_name = 'resources'
belongs_to :project_number
belongs_to :associate
end
Each time I uncomment the "has_many through" lines I receive an error viewing the project details page (show):
My show.html.erb has a the line highlighted
<dt>Project Hours: </dt> <dd><%= #project.project_numbers.sum(:hours_sold)%></dd>
With a rails error of:
/home/ruby/pda/app/models/project_number.rb:7: syntax error, unexpected =>
has_many :associates, through: => :resources
I have been through many blogs and think I have the relationship set up correctly however I don't understand the error at all. Why would a call to sum(hours) in project_number cause be triggering this error. Note: even with this line commented the next query against project_numbers fails. Can someone please help me understand what I am missing?
This line is syntactically wrong.
has_many :project_numbers, through: => :resources #wrong
This is the right syntax
has_many :project_numbers, :through => :resources # right
For Rails4,you can write it to
has_many :project_numbers, through: :resources
Do the same changes to the other association too.