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.
Related
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])
Writing a recipe app. Having a hell of a time getting this down.
My Models:
Recipe
has_many :recipe_ingredients
has_many :ingredients, through: :recipe_ingredients
Recipe_Ingredient
belongs_to :recipe
belongs_to :ingredient
Ingredient
has_many :recipe_ingredients, :dependent => :destroy
has_many :recipes, through: :recipe_ingredients
My routes are simple
resources :recipes // AND A FEW RANDOM OTHERS
In my Recipes Controller:
def new
#recipe = Recipe.new
recipe_ingredients = #recipe.recipe_ingredient.build
recipe_ingredients.ingredient.build
end
My Recipe Form:
<%= simple_form_for #recipe do |r| %>
<%= r.input :title, label: 'Recipe Name:' %>
<%= r.input :description, label: 'Recipe Description' %>
<%= r.simple_fields_for :recipe_ingredients do |ri| %>
<%= ri.input :quantity, label: "Quantity" %>
<%= ri.simple_fields_for :ingredients do |i| %>
<%= i.input :name, label: "name" %>
<% end %>
<% end %>
<%= r.button :submit %>
<% end %>
Not sure what I am doing wrong. The error is:
undefined method `recipe_ingredient' for #<Recipe:0x000001034d3650>
any ideas? Spent 2 nights on this.
The particular error seems to come from referencing #recipe.recipe_ingredient (singular), which should be pluralized, since it is a has_many relation. Try this in your RecipeController#new:
recipe_ingredients = #recipe.recipe_ingredients.build
Then, for the recipe_ingredients.ingredient, try using build_association instead:
recipe_ingredients.build_ingredient
I GOT TWO PROBLEMS:
-I'm stuck with creating a project which includes nested attributes for :position
-I got it nearly working for editing the project details plus the :position attribute, but the fields_for :assigned_projects ads all the fields for all users who are assigned to the project.
I have 3 Models:
class User < ActiveRecord::Base
has_many :assigned_projects
has_many :projects, :through => :assigned_projects
has_many :created_projects, :class_name => "Project", :foreign_key => :creator_id
end
class Project < ActiveRecord::Base
belongs_to :user
has_many :assigned_projects
has_many :users, :through => :assigned_projects
belongs_to :creator, :class_name => "User", :foreign_key => :creator_id
attr_accessible :name, :controlled, :currency, :creator_id, :assigned_projects
accepts_nested_attributes_for :assigned_projects#, :allow_destroy => true
end
class AssignedProject < ActiveRecord::Base
belongs_to :user, class_name: "User"
belongs_to :project, class_name: "Project"
attr_accessible :project_id, :user_id, :position, :project, :user, :user_attributes
accepts_nested_attributes_for :user
end
Each User can create a Project and is the Projects.creator
Each Project has_many Users through the join model Assigned_Project
Each User can have a different position in the project, so I want to save the :position in the join model AssignedProject.
if a user creates a Project, he should be able to edit the project attributes PLUS the :position attribute of the new join model.
Now the Form field for New.Project and Edit.Project
/project/new.htm.erb
<%= form_for( setup_new_project(#project) ) do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.fields_for :assigned_projects do |ff| %>
<%= ff.label :position %>
<%= ff.text_field :position%>
<% end %>
<%= f.submit "Add Project", class: "" %>
<% end %>
/project/edit.htm.erb
<%= form_for( setup_project(current_project) ) do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.fields_for :assigned_projects do |ff| %>
<%= ff.label :position %>
<%= ff.text_field :position%>
<% end %>
<%= f.submit "Update Project", class: "" %>
<% end %>
And I have the following setup methods as described in this article:
http://www.sitepoint.com/complex-rails-forms-with-nested-attributes/
module FormHelper
def setup_project(project)
project.assigned_projects ||= AssignedProject.new
project
end
def setup_new_project(project)
project.assigned_project = AssignedProject.new
project
end
end
I hope the problem is clear enough.
for creating a new project the current error message is:
undefined method `assigned_project='
15: <%= render 'shared/user_sidebar_menu' %>
16:
17: <div class="span4 offset1">
18: <%= form_for( setup_new_project(#project) ) do |f| %>
19:
20: <%= render 'shared/error_messages', object: f.object %>
21:
UPDATE: added projects_controller.rb
projects_controller.rb
class ProjectsController < ApplicationController
def new
#project = Project.new
end
def create
#project = Project.new(params[:project])
#project.creator = current_user
if #project.save
current_user.assigned_projects.create(project: #project)
redirect_to current_user
else
render 'new'
end
end
end
Update setup_new_project method as below:
def setup_new_project(project)
project.assigned_projects.build ## Updated this line
project
end
Use project.assigned_projects(Notice plural) instead of project.assigned_project(Notice singular WRONG).
User and AssignedProject model are in a 1-M relationship. So, you get dynamic method assigned_projects=(Notice plural), you are getting error as you called assigned_project=(Notice singular) which does not exist.
UPDATE
undefined method each for <AssignedProject:0x007ff7aa55b528>
Use project.assigned_projects.build instead of project.assigned_project = AssignedProject.new.
UPDATE 2
You are approaching this incorrectly. The form helpers are totally not required. All you need to do is update the new and create actions as below:
def new
#project = Project.new
#project.assigned_projects.build
end
and update the form_for in both new and edit view's as below:
<%= form_for(#project) do |f| %>
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
In this scenario I can insert values to the Member table and the Club table. But there is a field called :task in the memberships table that I want to submit a value to, and in the Memberships table member_id and club_id are inserted automatically by Rails. How do I include the task field in the form below? Thank you in advance.
View/form:
<%= form_for #member ,:url=>{:action =>"create"} do |f| %>
<%= f.text_field :email %>
<%= f.fields_for :clubs do |s| %>
<%= s.text_field :name %>
<% end %>
<%= f.submit "submit" %>
<% end %>
Models
class Member < ActiveRecord::Base
has_many :clubs ,:through=> :memberships
has_many :memberships
accepts_nested_attributes_for :clubs
attr_accessible :clubs_attributes
end
class Club < ActiveRecord::Base
has_many :members ,:through=>:memberships
has_many :memberships
end
class Memberships < ActiveRecord::Base
belongs_to :Member
belongs_to :Club
end
<%= f.fields_for :memberships do |m| %>
<%= m.text_field :task %>
<%= m.fields_for :clubs do |s| %>
<%= s.text_field :name %>
<% end %>
<% end %>