I have the following three models:
class User < ActiveRecord::Base
has_many :associations
has_many :pharmacies, :through => :accociations
end
class Associations < ActiveRecord::Base
belongs_to :user
belongs_to :pharmacy
end
class Pharmacy < ActiveRecord::Base
has_many :associations
has_many :users, :through => :accociations
end
When I open the users#show action I get the following error:
ActiveRecord::HasManyThroughAssociationNotFoundError in Users#show
Showing /Users/fanboy/Sites/ndt_app_v6/app/views/users/show.html.erb where line #14 raised:
Could not find the association :accociations in model User
Extracted source (around line #14):
11: <div class="span8">
12: <%= form_for(#user) do |f| %>
13: <%= f.label :pharmacy_ids, "Pharmacies" %><br />
14: <%= f.collection_select :pharmacy_ids, Pharmacy.order(:name), :id, :name, {}, {multiple: true} %>
15: <% end %>
16: </div>
17: </div>
Basically I would like to allow Users to associate themselves with a Pharmacy. Instead I get the error above, any help would be much appreciated.
Your comment is way off, and the linked documentation has nothing to do with your problem.
The problem with your code is that you have a brutally obvious typo in several places. Your association is called associations, but your :through uses accociations.
Associations vs ACCociations.
Rails is telling you exactly what the error is:
Could not find the association :accociations in model User
The reason your linked documentation fixed your problem is that you probably spelled the new association name correctly. It's pretty important that you spell things correctly when programming, and such an obvious typo should really leap out at you.
Related
I need some advice on building a has many through relationship between USER, THING and EXTRA models.
My USER model is slightly modified inside Devise gem and is noted as Creator whereas other models belonging to USER receive :created_things form.
In my app, USERS create THINGS can later add EXTRAS to their THINGS.
I chose has many through because I want to have unique data on all three models and be able to call both THINGS and EXTRAS from the USER "CREATOR" model.
I have built this many different ways and after 10 years of solving my problems by reading stackoverflow, I am finally submitting this request for support! Thank you for your help.
I have tried creating user and extra references on the THING model and declaring nested attributes in the USER and THING model. I have tried several examples from stackoverflow inside the create and new methods but nothing seems to work.
class User < ApplicationRecord
has_many :created_things, class_name: Thing, foreign_key:
:creator_id, :dependent => :destroy
has_many :extras, through: :created_things
accepts_nested_attributes_for :extras, :reject_if => :all_blank,
allow_destroy: true
class Thing < ApplicationRecord
belongs_to :creator, class_name: User
has_many :extras
accepts_nested_attributes_for :extras, :reject_if => :all_blank,
allow_destroy: true
class Extra < ApplicationRecord
belongs_to :creator, class_name: User, inverse_of: :thing
belongs_to :created_things
Members Index.html.erb
<% if thing.extras.exists? %>
<% thing.extras.each do |extra| %>
<%= extra.title %> <%= link_to "[+]", edit_extra_path(extra) %>
<% end %>
<% else if thing.extras.empty? %>
<%= link_to "+1 EXTRA", new_extra_path(current_user) %>
<% end %>
<% end %>
class MembersController < ApplicationController
before_action :authenticate_user!
def index
#user = current_user
#created_extras = #user.extras
#created_things = #user.created_things
end
class ExtrasController < ApplicationController
def new
#extra = Extra.new
end
def create
#extra = current_user.extras.build(extra_params)
if #extra.save
I am able to create a new EXTRA but the :thing_id remains nul as it does not display when called on the show extra view. Therefore I am not surprised that when I return to the member index page that my thing.extras.exists? call is returning false and the created extra never displays under the THING view. My attempts to modify the extra controller have failed and I some of my reading sugested the extras controller is not necessary in this relationship so I am really at a loss on how this is built. I'm assuming I am missing something in new and create methods maybe in things or user controller? Perhaps I'm missing something in routes resources? Any advice is greatly appreciated. Thank you.
Ok, I figured it out. I really didn't need has many through for this model and I did a lot of testing of the syntax on each model.rb and in the end was able to figure it out from this stackoverflow . . .
[Passing parent model's id to child's new and create action on rails
Here are my the various parts of setting up a has many and belongs to relationship with nested attributes.
class Thing < ApplicationRecord
belongs_to :creator, class_name: User
has_many :extras, inverse_of: :thing, :dependent => :destroy
accepts_nested_attributes_for :extras, allow_destroy: true
class Extra < ApplicationRecord
belongs_to :thing, inverse_of: :extras
extras_controller.rb
class ExtrasController < ApplicationController
def new
#extra = Extra.new(thing_id: params[:thing_id])
end
def create
#user = current_user
#extra = Extra.new(extra_params)
#extra.user_id = #user.id
if #extra.save
flash[:success] = "You have added a new Extra!"
redirect_to #extra #extras_path later
else
flash[:danger] = "The form contains errors"
render :new
end
end
edit.html.erb things
<% if #thing.extras.exists? %>
<p>current extras associated with <%= #thing.title %>: </p>
<% #thing.extras.each do |extra| %>
<p><%= extra.title %> <%= link_to "[+]", edit_extra_path(extra) %>
/ <%= link_to "[-]", extra_path(extra), method: :delete %> </p>
<% end %>
<% end %>
<%= link_to "+1 EXTRA", new_extra_path(thing_id: #thing.id) %>
<%= render 'things/form' %>
Three models linked via has_many :through
class Bozza < ActiveRecord::Base
has_many :accessoryvolumes, :dependent => :destroy
has_many :accessories, through: :accessoryvolumes
belongs_to :lavorazione
class Accessory < ActiveRecord::Base
has_many :accessoryvolumes
has_many :bozzas, through: :accessoryvolumes
class Accessoryvolume < ActiveRecord::Base
belongs_to :accessory
belongs_to :bozza
In the view for bozza, the attributes for bozza are accessible
<% #bozza.accessoryvolumes.each do |accessoryvolume| %>
<%= accessoryvolume.numero %>
<%= accessoryvolume.bozza_id %>
<%= accessoryvolume.bozza.lavorazione.name %>
<%= accessoryvolume.accessory_id %>
<%= accessoryvolume.accessory.name %>
save for the last item. Any attribute for the relationship to accessory generates and
undefined method `name' for nil:NilClass
evan though accessory_id has a value. How is the related attribute in one instance being picked up and not the other?
The issue is with the plural handling of "accessory". it was a nasty suspicion for many hours....
This issue arises rather frequently. Pony up and come up with a name that cannot be interpreted mistakenly by rails or someone, somehow, somewhere. Avoid nouns that pluralize irregularly. Moreso when dealing with foreign languages.
Now
class Accessorio < ActiveRecord::Base
has_and_belongs_to_many :lavoraziones
has_many :accessoryvolumes
has_many :bozzas, through: :accessoryvolumes
and
<%= accessoryvolume.accessorio.nome %>
runs as expected
I can't get my collection_select to work.. I have looked at these two links, which have conflicting syntax, and can't seem to get either to work. I've also read the Rails documentation.
Rails 3 build a select tag with has_many belongs_to association
Undefined method 'merge' for "test":String - Rails 3.1
I get different errors when I try the different syntax, but here is my current error.
undefined method `map' for nil:NilClass
Models
class Instruction < ActiveRecord::Base
attr_accessible :exercise_id, :order, :sentence, :instruction_type_id
belongs_to :exercise
belongs_to :instruction_type
end
class InstructionType < ActiveRecord::Base
has_many :instructions
has_many :exercises, :through => :instructions
attr_accessible :name
end
Instruction Controller
def create
#instruction = Instruction.new(params[:instruction])
end
Instruction Form
<div class="field">
<%= f.label :instruction_type_id %><br />
<%= f.collection_select(:instruction_type_id, #instruction_types, :id, :name, :prompt => 'Please select country') %>
<%= f.label :order %><br />
<%= f.number_field :order %>
</div>
Thanks everyone.
Newbie question here.
I have two models which are related to each other:
class Relationship < ActiveRecord::Base
...
attr_accessible :source_item_id, :target_item_id
belongs_to :target_item, :class_name => "Item"
belongs_to :source_item, :class_name => "Item"
belongs_to :user
...
end
and:
class Item < ActiveRecord::Base
...
attr_accessible :address
...
end
Now, within my form, I already know the source_item_id. I want to be able to enter an address into the form, and create both a target_item, and the associated Relationship.
<%= form_for #new_relationship do |f| %>
<% #new_relationship.source_item_id = #current_item.id %>
<%= f.hidden_field :source_item_id %>
<%= f.submit "New Relationship" %>
<% end %>
You generally do the relationship in the controller and let the form just collect the data. If you are asking how to have a form with two models, check out this post here. I hope I understood your question right !!!
I have been getting all kinds of conflicting information regarding this basic question, and the answer is pretty crucial to my current problems. So, very simply, in Rails 3, is it allowed or not allowed to use accepts_nested_attributes_for with a belongs_to relationship?
class User < ActiveRecord::Base
belongs_to :organization
accepts_nested_attributes_for :organization
end
class Organization < ActiveRecord::Base
has_many :users
end
In a view:
= form_for #user do |f|
f.label :name, "Name"
f.input :name
= f.fields_for :organization do |o|
o.label :city, "City"
o.input :city
f.submit "Submit"
Nested attributes appear to work fine for a belongs_to association as of Rails 4. It might have been changed in an earlier version of Rails, but I tested in 4.0.4 and it definitely works as expected.
The doc epochwolf cited states in the first line "Nested attributes allow you to save attributes on associated records through the parent." (my emphasis).
You might be interested in this other SO question which is along the same lines as this one. It describes two possible solutions: 1) moving the accepts_nested_attributes to the other side of the relationship (in this case, Organization), or 2) using the build method to build the Organization in the User before rendering the form.
I also found a gist that describes a potential solution for using accepts_nested_attributes with a belongs_to relationship if you're willing to deal with a little extra code. This uses the build method as well.
For belongs_to association in Rails 3.2, nested model needs the following two steps:
(1) Add new attr_accessible to your child-model (User model).
accepts_nested_attributes_for :organization
attr_accessible :organization_attributes
(2) Add #user.build_organization to your child-controller (User controller) in order to create column organization.
def new
#user = User.new
#user.build_organization
end
For Ruby on Rails 5.2.1
class User < ActiveRecord::Base
belongs_to :organization
accepts_nested_attributes_for :organization
end
class Organization < ActiveRecord::Base
has_many :users
end
Just got to your controller, suppose to be "users_controller.rb":
Class UsersController < ApplicationController
def new
#user = User.new
#user.build_organization
end
end
And the view just as Nick did:
= form_for #user do |f|
f.label :name, "Name"
f.input :name
= f.fields_for :organization do |o|
o.label :city, "City"
o.input :city
f.submit "Submit"
At end we see that #user3551164 have already solved, but now (Ruby on Rails 5.2.1) we don't need the attr_accessible :organization_attributes