nested attributes not displaying form correctly - ruby-on-rails

I have a form from user
<%= form_for(#user) do |f| %>
<%= f.fields_for :businesses do |field| %>
<div class="field">
<%= field.label :address %>
<%= field.text_field :address %>
</div>
<div class="field">
<%= field.label :city %>
<%= field.text_field :city %>
</div>
<% end %>
<% end %>
It does not display my fields, but when i change businesses to business, then it shows, or if I remove the f from f.fields_for. But I don't think it properly saves into database.
my user model
class User < ActiveRecord::Base
has_many :businesses
accepts_nested_attributes_for :businesses
en
my business model
class Business < ActiveRecord::Base
attr_accessible :user_id, :address, :city
belongs_to :user
end
my bussiness migration
class CreateBusinesses < ActiveRecord::Migration
def change
create_table :businesses do |t|
t.integer :user_id
t.string :address
t.string :city
t.timestamps
end
end
end
Any suggestions as to what I'm doing wrong?
Thanks

You should build a business before it can display a form for it:
#user.businesses.build
Use that before using fields_for
Also check out this great gem for managing nested forms:
https://github.com/ryanb/nested_form

Related

Can't figure out how to add polymorphic tags in a rails app

I have a sample rails app with a list of users. And I wanted to experiment with polymorphic tags.
At this moment I can create tags for users through console in the following way
User.first.tags.create(name: "new tag name")
But have problems with adding them through webform
Here's what I did:
rails g model Tag name taggable:references{polymorphic}
generated the following migration
class CreateTags < ActiveRecord::Migration[5.1]
def change
create_table :tags do |t|
t.string :name
t.references :taggable, polymorphic: true
t.timestamps
end
end
end
tag model
class Tag < ApplicationRecord
belongs_to :taggable, polymorphic: true
end
user model
class User < ApplicationRecord
has_many :tags, as: :taggable
end
Tags field
<%= form_with(model: user, local: true) do |form| %>
...
<div class="field">
<%= form.label :tag_list %>
<%= form.text_field :tag_list, placeholder: "tags separated by comma" %>
</div>
...
<% end %>
I also found the following code but getting You cannot call create unless the parent is saved error.
added the following setter to user model and added :tag_list to strong params of user
def tag_list=(vals)
self.tags = vals.split(", ").each do |val|
tags.where(name: val.strip).first_or_create!
end
end
You can add tags with nested form
user model
class User < ApplicationRecord
has_many :tags, as: :taggable
accepts_nested_attributes_for :tags
end
in your form
<%= form_with(model: user, local: true) do |form| %>
...
<div class="field">
<% form.fields_for :tags do |t| %>
<%= u.text_field :tag_name %>
<% end %>
</div>
...
<% end %>
in your controller , please add other attribute as well
params.require(:user).permit( tags_attributes: [:id,:tag_name])

Rails nested form with three models

I have three models
class Property < ActiveRecord::Base
has_many :contact
accepts_nested_attributes_for :contact
has_many :business
accepts_nested_attributes_for :business
end
class Business < ActiveRecord::Base
belongs_to :property
has_many :contact
end
class Contact < ActiveRecord::Base
belongs_to :property
belongs_to :business
end
I created a form that creates the Property with a nested contact and a nested business, how can I get that business to have a nested contact?
Here is my form
<%= form_for(#property) do |f| %>
<div class="field">
<%= f.label :address %><br>
<%= f.text_field :address %>
</div>
<% end %>
<%= f.fields_for :contact do |contact_form| %>
<div class="field">
<%= f.label :contact_title, "Title" %><br>
<%= contact_form.text_field :title %><br>
<%= f.label :contact_name, "Name" %><br>
<%= contact_form.text_field :name %><br>
</div>
<% end %>
<%= f.fields_for :business do | business_form| %>
<div class="indv-biz field">
<%= f.label :business_name, "Name" %><br>
<%= business_form.text_field :name %><br>
</div>
<div class="business-contact">
<p>Business Contact</p>
<%= f.fields_for :business_contact do | business_contact | %>
<div class="field">
<%= business_contact.label :contact_title, "Title" %><br>
<%= business_contact.text_field :title %><br>
<% end %>
<% end %>
I can get it to save so the business is connected to the property and the contact is connected to the property but I can't figure out how to get a contact connected to the business
Thanks
You should try deep nesting like this. your requirement is a property have many business which in-turn have many contacts. In this case, you actually should do is setting nested form for property with business and that business should have nested form of contacts. The below one will work for you.
Form
nested_form_for #property do |f|
...
f.fields_for :bussiness do |bussiness_form|
...
bussiness_form.fields_for :contact_form do |contact_form|
....
end
end
end
end
Models
class Property < ActiveRecord::Base
has_many :contact
has_many :business
accepts_nested_attributes_for :business
end
class Business < ActiveRecord::Base
belongs_to :property
has_many :contacts
accepts_nested_attributes_for :contacts
end
class Contact < ActiveRecord::Base
belongs_to :property
belongs_to :business
end
controller
def property_params
params.require(:property).permit(:id,.., :bussiness_attributes => [:id,.., , :contacts_attributes => [:id, ..]])
end

Rails - checkbox form from array

I have a admin controller to create "Locations", inside of which is a form. In the form you can create a new "Location" and give it a name, description, and "exits".
<%= form_for #location do |f| %>
<p>
<%= f.label :name %><br>
<%= f.text_field :name %>
</p>
<p>
<%= f.label :description %><br>
<%= f.text_area :description %>
</p>
<p>
Exits:
<br/>
<% #locations.each do |e| %>
<%= f.label :locations %>
<%= f.check_box :locations %>
<% end %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
#locations is all of the available locations to set up as an "exit". I'm trying to create an array of locations inside of the new location using checkboxes to check whether or not they should be set as "exits", but not really sure how to proceed since i'm just teaching myself and it's day one.
I'm also wondering how to set up the "exits" in the Location model. Right now i have:
class Location < ActiveRecord::Base
has_many :locations
validates :name, presence: true, length: { minimum: 1 }
validates :description, presence: true
end
created with:
class CreateLocations < ActiveRecord::Migration
def change
create_table :locations do |t|
t.string :name
t.text :description
t.references :location, index: true, foreign_key: true
t.timestamps null: false
end
end
end
But i would like to have them referenced as "exits" not "locations" (ie Location.exits instead of Location.locations).
UPDATE
I've updated the form to use the collection_check_boxes helper
<%= f.collection_check_boxes(:exit_ids, #locations, :id, :name) do |cb| %>
<%= cb.label %> <%= cb.check_box %> <br/>
<% end %>
So I have this in the create action now
def create
#location = Location.new(location_params)
if #location.save
params[:location][:exit_ids].each do |e|
if e.to_i > 0
tempLocation = Location.find(e.to_i)
#location.allowExitTo(tempLocation)
end
end
redirect_to #location
else
render 'new'
end
end
Which goes allows exits through:
def allowExitTo(other_location)
exit_locations.create(to_id: other_location.id)
end
creating an exit relationship with:
class Exit < ActiveRecord::Base
belongs_to :from, class_name: 'Location'
belongs_to :to, class_name: 'Location'
validates :from_id, presence: true
validates :to_id, presence: true
end
Hope I'm on the right track. It seems to work so I guess so.
Edit: Sorry, I must have had a brain-fart or something. You're not doing a simple has-many and belongs-to relationship, you want a has-many-and-belongs-to-many relationship. That's more complicated than I know how to explain. But this answer explained it very well: Many-to-many relationship with the same model in rails?
You can get Location#exits instead of Location#locations by changing the name of the has_many relation like this:
class Location < ActiveRecord::Base
# has_many :locations Instead of this...
has_many :exits, :class_name => 'Location' # ...Do this
validates :name, presence: true, length: { minimum: 1 }
validates :description, presence: true
end
This is called a self-join. You're associating a model with itself.
Keep in mind that this will make Location#locations unavailable.
Then in your form you would do something like:
<% #locations.each do |e| %>
<%= f.label :exit %>
<%= f.check_box :exit %>
<% end %>
The Ruby on Rails site has a nice guide about associations, includeing self-joins like what you're asking about: http://guides.rubyonrails.org/association_basics.html#self-joins
If you like RailsCasts: http://railscasts.com/episodes/163-self-referential-association

How are parameters passed for nested attributes in Rails?

I have two models, Ingredients and Foods:
class Food < ActiveRecord::Base
belongs_to :user
has_many :ingredients
accepts_nested_attributes_for :ingredients
attr_accessible :name, :price
end
class Ingredient < ActiveRecord::Base
belongs_to :user
belongs_to :food
attr_accessible :ingredient_name, :quantity_used
end
The schemas for the two models are as follows:
create_table "foods", :force => true do |t|
t.string "name"
t.integer "user_id"
t.float "price"
t.string "ingredient_name"
end
create_table "ingredients", :force => true do |t|
t.string "ingredient_name"
t.integer "user_id"
t.integer "food_id"
t.integer "quantity_used"
end
I'm creating a form for Food which also creates/updates the Ingredient table as well. I have the form working, and the submit button updates the correct attributes, but I have other attributes in each table that I want to update as well. For example, in the Food Controller, I want to do something like ingredient.user_id = current_user.id. I understand I can access things through params[:food], but how do I access individual fields which aren't being updates by the form?
Right now, my form is:
<%= form_for(#food) do |f| %>
<div class="field">
<%= f.label :Name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :price %><br />
<%= f.number_field :price %>
</div>
<div>
<%= f.fields_for :ingredients do |builder| %>
<%= builder.label "Ingredient Used:" %>
<%= builder.text_field :ingredient_name %><br />
<%= builder.label "Quantity Used:" %>
<%= builder.text_field :quantity_used %><br />
<% end %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
How do I access this specific Food's ingredients in the Food#create action?
Thanks!
You might need to add :ingredients_attributes to attr_accessible in your Food model.
You can mess about with the params hash in the controller by iterating over the :ingredients_attributes or you can use assign_attributes.

HABTM assosiation in Rails 3

I have two models User and Project
User -> has_many :projects ,:dependent=>:destroy
Project -> has_and_belongs_to_many :users
I also created a mapping table projects_users.
When i tried to delete user its corresponding projects are not deleting from projects table ,and mapping table also shows same data without change ,only thing happening is my user data is deleting.
Is there any way to delete associated data ,and to remove entries from mapping table.
Project Model
class Project < ActiveRecord::Base
attr_accessible :name ,:user_ids
has_and_belongs_to_many :users
end
User Model
class User < ActiveRecord::Base
attr_accessible :name
has_many :projects
end
AssosiationTable
class ProjectsUsers < ActiveRecord::Migration
def up
create_table :projects_users, :id => false do |t|
t.references :project
t.references :user
end
end
def down
drop_table :projects_users
end
end
User: _form.html.erb
<%= semantic_form_for #user do |f| %>
<%= f.inputs do %>
<%= f.input :name %>
<% end %>
<%= f.actions %>
<% end %>
Project: _form.html.erb
<%= semantic_form_for #project do |f| %>
<%= f.inputs do %>
<%= f.input :name %>
<%= f.input :users, :as => :check_boxes %>
<% end %>
<%= f.actions %>
<% end %>
Thanks in advance.

Resources