Nested form has_many through issue - ruby-on-rails-4

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"},

Related

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

(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?

Devise - Nested Attributes - Customer --> Customer_addresses --> Address

I have been trying to create a relationship like the database listed below, using devise to create the Customer table. I have created migrations for the other tables using the ID ing though table-names and ID. My models look like the below. I know I have gone overboard with the has_many relationships, but I have been trying this all day.
Can anyone help or show the correct way to set up this so that I can create, edit and update addresses on the user. I have managed success with simple nested attributes say Customer/ Direct to address but when I place the table in the middle I just cant get the address attributes to show or update.
I guess there is a more complex edit, create , destroy method that needs to be implemented also.
I'm also getting lost with how to allow strong params on this type of nesting as most examples i can find only have it connected to tables that hold the user_id in them and not one that is connected through another table.
cheers in advance for the guidance.
DataModel image here
Tables
customers / Devise table defaults
customer_addresses
id
address_id
address_type_id
customer_id
addresses
id
address xzy Marua Road
other details / Front house
address_type
id
address_type / Home , Business etc
address_type_description / Where you live etc
class Customer < ActiveRecord::Base
has_many :customer_addresses
has_many :addresses
has_many :address_types
accepts_nested_attributes_for :customer_addresses
accepts_nested_attributes_for :address_types
accepts_nested_attributes_for :addresses
end
class UserAddress < ActiveRecord::Base
has_many :customer
has_many :address_types
has_many :addresses
end
class AddressType < ActiveRecord::Base
belongs_to :customer_address
end
class Address < ActiveRecord::Base
belongs_to :user_address
end
<div class="field">
<%= f.fields_for :user_addresses do |ff| %>
<div>
<%= ff.label :address_id %><br />
<%= ff.text_field :address_id %>
<%= ff.fields_for :address do |fff| %>
<%= fff.label :address %><br />
<%= fff.text_field :address %>
<% end %>
<% end %>
</div>
</div>
user controller params
def user_params
params.require(:user).permit(:id, :username, :first_name, :last_name, :email, :password, :password_confirmation,
user_address_attributes:[:user_is, :address_id, :address_type_id],
addresses_attributes:[:id, :address, :other_address_details ],
address_type_attributes:[ :id, :address_type])
end
The associations you defined should have been like the following
class Customer
has_many :customer_addresses
has_many :addresses, :through => :customer_addresses
has_many :address_types, :through => :customer_addresses
end
class Address
has_many :customer_addresses
has_many :customers, :through => :customer_addresses
has_many :address_types, :through => :customer_addresses
end
class AddressType
has_many :customer_addresses
has_many :customers, :through => :customer_addresses
has_many :addresses, :through => :customer_addresses
end
class CustomerAddress
belongs_to :customer
belongs_to :address
belongs_to :address_type
end
class Customer < ActiveRecord::Base
has_many :customer_addresses
accepts_nested_attributes_for :customer_addresses
end
class AddressType
has_many :customer_addresses
end
class CustomerAddress
belongs_to :address_type
belongs_to :customer
belongs_to :address
accepts_nested_attributes_for :address
after_initialize :add_address, unless: 'address.present?'
def add_address
self.build_address
end
end

Rails 4: how to use form_for (has_many :through with extra attributes)

I have a Store model, Product model, and a StoreProduct model to form a many-to-many relationship between stores and products.
The StoreProduct model, on top of store_id and product_id, has an attribute price:float.
I'm struggling to figure out how I can design a form to create a new product given the store. Is it better off making a form for a new StoreProduct object? What is the conventional way of doing this?
store.rb
class Store < ActiveRecord::Base
validates :name, presence: true
has_many :store_products
has_many :products, through: :store_products
end
product.rb
class Product < ActiveRecord::Base
validates :name, presence: true
validates_numericality_of :price, on: :create
has_many :reviews
has_many :users, through: :reviews
has_many :store_products
has_many :stores, through: :store_products
end
store_product.rb
class StoreProduct < ActiveRecord::Base
belongs_to :store
belongs_to :product
end

Trying to model the relationship between two people in rails

I have the following two simple classes:
class Person < ActiveRecord::Base
has_many :parent_child_assignments
has_many :children, :through => :parent_child_assignments
has_many :parents, :through => :parent_child_assignments
end
class ParentChildAssignment < ActiveRecord::Base
belongs_to :parent, :class_name => "Person"
belongs_to :child, :class_name => "Person"
end
created from the following rails commands
rails generate model Person name:string
rails generate model ParentChildAssignment parent_id:integer child_id:integer
I can get one direction (joe.children or joe.parents) to work but not both
Someone must have asked this question before, but I can't find it.
Thanks in advance.
The classes should look like:
class Person < ActiveRecord::Base
has_many :parent_child_assignments_as_parent, class_name: 'ParentChildAssignment', :foreign_key => :parent_id
has_many :parent_child_assignments_as_child, class_name: 'ParentChildAssignment', :foreign_key => :child_id
has_many :children, :through => :parent_child_assignments_as_parent
has_many :parents, :through => :parent_child_assignments_as_child
end
class ParentChildAssignment < ActiveRecord::Base
belongs_to :parent, :class_name => "Person", :foreign_key => :parent_id
belongs_to :child, :class_name => "Person", :foreign_key => :child_id
end