In my app users has many companies, and companies has many users, companies has many divisions and users have different division in different company for example User with id 1 belongs to Company 1 and Division 2 and to Company 2 Division 3
User.rb
class User < ActiveRecord::Base
has_many :companies, through: :users_companies
has_many :users_companies
has_many :divisions, through: :users_divisions
has_many :users_divisions
has_many :users_roles, dependent: :destroy
has_many :roles, through: :users_roles
end
Company.rb
class Company < ActiveRecord::Base
#before_create :create_division
has_many :users_companies
has_many :users, through: :users_companies
has_many :divisions, dependent: :destroy
has_many :positions
end
Division.rb
class Division < ActiveRecord::Base
has_ancestry
belongs_to :company
has_many :users, through: :users_divisions
has_many :users_divisions
end
UsersCompany.rb
class UsersCompany < ActiveRecord::Base
belongs_to :user
belongs_to :company
end
UsersDivision.rb
class UsersDivision < ActiveRecord::Base
belongs_to :user
belongs_to :division
belongs_to :company
end
UsersDivision table have structure
id|user_id|division_id|company_id
when create all be fine
UsersDivision.create!(user: #user, division_id: params[:user][:division_ids], company_id: #company.id)
but when I try to update #user in table UsersDivision column company_id will be nill.
def update
#company = Company.find(params[:company_id])
#user = User.find(params[:id])
if #user.update(user_params)
redirect_to :back
end
end
How to pass params :company_id to update action?
<div class="edit-registration-container">
<%= #user.full_name %>
<%= form_for([#company, #user]) do |f| %>
<%= f.label :last_name, "Фамилия" %><br />
<%= f.text_field :last_name, type: "text" %>
<%= f.label :first_name, "Имя" %><br />
<%= f.text_field :first_name, type: "text" %>
<%= f.label :middle_name, "Отчество" %><br />
<%= f.text_field :middle_name, type: "text" %>
<%= f.label :division_ids, "Подразделение" %><br />
<%= f.select :division_ids, #divisions_select %><br />
<%= f.hidden_field :company_id, value: #company.id %>
<%= f.fields_for :positions, #position do |ff| %>
<%= ff.label :name, "Должность" %>
<%= ff.text_field :name, type: "text" %>
<%= ff.hidden_field :company_id, value: #company.id %>
<% end %>
<%= hidden_field_tag "user[role_ids][]", nil %>
<% Role.all.each do |role| %>
<%= check_box_tag "user[role_ids][]", role.id, #user.role_ids.include?(role.id), id: dom_id(role) %>
<%= label_tag dom_id(role), role.name %><br>
<% end %>
<%= f.submit "Сохранить", class: "login loginmodal-submit", type: "submit" %>
<% end %>
</div>
You need to permit that parameter to be accessible, so add it in your
user controller params permit:
params.require(:user).permit(YOUR PARAMETERS, {:company_id => []})
Then you can call it using:
params["user"]["company_id"]
I think you can simply do this inside your update action:
#company = Company.find(params["user"]["company_id"])
Here is my working example form:
<%= form_for :user, :url => custom_users_path do |f| %>
<%= f.text_field :name %>
<%= f.hidden_field :company_id, :value => Company.find(1).id %> #4
<%= f.submit "Submit" %>
After I submit, inside my custom action my params["user"]["company_id"] would have this value: 4
Related
HI I am trying to implement the MTI in my application. I have a Person Model and 2 models inheriting from it: Client and TeamMember. When creating a Team Member I want to save to to database vallues for both person (first and last name, email etc) and team member(experience level, type of team, if lead or not). I am using the nested attributes form so in my team member form I am nesting the person fields. Unfortunatellly I am getting "Can't mass-assign protected attributes: person" error when trying to save. Can anyone tell me how this can be solved? Thanks!
Models:
UPDATED TeamMember class but still the same error
also tried people_attributes and persons_attributes and none of these worked
class TeamMember < ActiveRecord::Base
has_many :project_team_members
has_many :projects, through: :project_team_members
has_one :person, as: :profile, dependent: :destroy
accepts_nested_attributes_for :person
attr_accessible :person_attributes, :experience_level, :lead, :qualification, :team
end
class Person < ActiveRecord::Base
belongs_to :company
belongs_to :profile, polymorphic: true
attr_accessible :email, :first_name, :last_name, :phone_number, :profile_id, :profile_type
end
Controller as follows:
class TeamMembersController < ApplicationController
def create
person = Person.create! { |p| p.profile = TeamMember.create!(params[:team_member]) }
redirect_to root_url
end
and the view:
<%= form_for(#team_member) do |f| %>
<%= f.fields_for :person do |ff| %>
<div>
<%= ff.label :first_name %>
<%= ff.text_field :first_name %>
</div>
<div>
<%= ff.label :last_name %>
<%= ff.text_field :last_name %>
</div>
<div>
<%= ff.label :phone_number %>
<%= ff.text_field :phone_number %>
</div>
<div>
<%= ff.label :email %>
<%= ff.text_field :email %>
</div>
<div>
<%= ff.label :company_id %>
<%= ff.text_field :company_id %>
</div>
<% end %>
<div class="field">
<%= f.label :team %><br />
<%= f.text_field :team %>
</div>
<div class="field">
<%= f.label :experience_level %><br />
<%= f.text_field :experience_level %>
</div>
<div class="field">
<%= f.label :qualification %><br />
<%= f.text_field :qualification %>
</div>
<div class="field">
<%= f.label :lead %><br />
<%= f.check_box :lead %>
</div>
<div class="actions">
<%= f.submit %>
</div>
UPDATED TeamMembersController (Solution thanks to the courtesy of Tiago)
def new
#team_member = TeamMember.new
#team_member.build_person
respond_to do |format|
format.html # new.html.erb
format.json { render json: #team_member }
end
end
def create
#team_member = TeamMember.create!(params[:team_member])
redirect_to root_url
end
To mass assign attributes in a nested form, you'll need to specify:
class TeamMember < ActiveRecord::Base
has_many :project_team_members
has_many :projects, through: :project_team_members
has_one :person, as: :profile, dependent: :destroy
:experience_level, :lead, :qualification, :team #what is this line doing??
accepts_nested_attributes_for :person
attr_accessible :person_attributes
end
EDIT:
In the action called before the form you need to build person. Like:
#team_member = TeamMember.new
#team_member.build_person
Then you'll have one person (non-persisted) associated with #team_member.
I'm trying to manage invitations to an event with a "participation" model. I'd like that, when I invite a user, i could insert his name in the form, instead of user_id.
user.rb
class User < ActiveRecord::Base
attr_accessible :id, :name
has_many :participations
end
participation.rb
class Participation < ActiveRecord::Base
attr_accessible :event_id, :user_id
belongs_to :event
belongs_to :user
end
views/participations/new.html.erb
<%= form_for(#participation) do |f| %>
<%= f.hidden_field :event_id, value: #event.id %>
<%= f.label :user_id, 'User Id' %>
<%= f.number_field :user_id %>
<%= f.submit 'Invite' %>
<% end %>
How can i do?
Try by this:
<%= form_for(#participation) do |f| %>
<%= f.hidden_field :event_id, value: #event.id %>
<%= f.label :user_id, 'User Id' %>
<%=f.collection_select :user_id,User.all,:id,:name,:label => "User" ,:include_blank => false%>
<%= f.submit 'Invite' %>
<% end %>
You may turn include_blank to true or false as you wish to always have a user or not.
Feel free to ask for more if this doesn't solve your problem.
I have a model Contact which has a many-to-many relationship with Company:
class Contact < ActiveRecord::Base has_many :contactcompanies
has_many :companies, through: :contactcompanies
Company model:
class Company < ActiveRecord::Base
has_many :contactcompanies
has_many :contacts, through: :contactcompanies
ContactCompany:
class ContactCompany < ActiveRecord::Base
belongs_to :company
belongs_to :contact
contacts_controller.rb:
def new
#contact = Contact.new
#all_companies = Company.all
#contact_company = #contact.contactcompanies.build
end
contact create form where I want to have a multiple select for companies:
<%= form_for #contact do |f| %>
<%= f.label :first_name %>
<%= f.text_field :first_name %>
<%= f.label :last_name %>
<%= f.text_field :last_name %>
<%= f.label :image_url %>
<%= f.text_field :image_url %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= fields_for(#contact_company) do |cc| %>
<%= cc.label "All Companies" %>
<%= collection_select(:companies, :id, #all_companies, :id, :name, {}, { :multiple => true }) %>
<% end %>
<div class="form-action">
<%= f.submit nil, :class => 'btn btn-primary' %>
<%= link_to t('.cancel', :default => t("helpers.links.cancel")),
contacts_path, :class => 'btn' %>
</div>
<% end %>
My issue is when I go to /contacts/new I get this error:
Circular dependency detected while autoloading constant Contactcompany
Any ideas? I'm searching for hours without success. Thanks
You have declared your class as "ContactCompany"
This implies:
has_many :contact_companies
has_many :contacts, through: :contact_companies
Without the underscore, it is looking for a class named Contactcompany, which does not exist.
I have nested forms dealing with 3 models. Job, Employer, User
The form on the jobs controller needs to create a job, employer and user.
The Job and Employer forms are working correctly, however when I add the User nested form I get the error "undefined method `model_name' for NilClass:Class"
I'm completely confused as to why.
Here is my code:
Job Model
attr_accessible :category, :employer_id, :employer_attributes, :user_attributes
belongs_to :employer
accepts_nested_attributes_for :employer, :user
has_many :applications
has_many :users, :through => :applications
Employer model
attr_accessible :companyname, :email, :logo, :password, :url
has_many :jobs
belongs_to :user
User Model
attr_accessible :admin, :cv, :name, :password, :website, :password_confirmation
has_many :applications
has_many :jobs, :through => :applications
has_one :employer
_form.html.erb
<%= form_for(#job) do |f| %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.fields_for :employer do |builder| %>
<%= builder.label :companyname, "Company Name" %>
<%= builder.text_field :companyname %>
<% end %>
<%= f.fields_for :user do |builder| %>
<%= builder.label :email, "Email" %>
<%= builder.text_field :email %>
<%= builder.label :password, "Password" %>
<%= builder.text_field :password %>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Job Controller
def new
#job = Job.new
#job.employer = #job.build_employer
#job.user = #job.build_user
To doesn't look like your Job model has a user method. You may need to add
belongs_to :user
I'm new to rails and just cant get that problem solved.
i have 3 models. Orders, Products and LineItems.
I want to have a order form with checkboxes for each product. User selects appropriate products and submits the order.
I cannot get the form to create the correct hash.
class Order < ActiveRecord::Base
attr_accessible :account_id, :user_id
has_many :line_items, :dependent => :destroy
end
class LineItem < ActiveRecord::Base
attr_accessible :account_id, :product_id, :order_id
belongs_to :orders
belongs_to :product
end
Here the view:
<%= form_for 'line_items[]' do |f| %>
<%= f.select :account_id, options_from_collection_for_select( Account.all,
:id, :name ), :prompt => 'Select Account' %>
<% Product.all.each do |product| %>
<div>
<%= check_box_tag 'line_items[product_ids][]', product.id %>
</div>
<% end -%>
<div>
<%= f.submit 'save' %>
</div>
thanks!
You would need to use accepts_nested_attributes_for in your model to enable nested atributes from associated models. You may also want to check out this railscast and adapt to your needs.
For example in the orders model:
class Order < ActiveRecord::Base
attr_accessible :account_id, :user_id
has_many :products #This makes the association to products
has_many :line_items, :dependent => :destroy
accepts_nested_attributes_for :products #This allows the attributes from products accessible
end
Then the form could be:
<%= form_for #order do |f| %>
<%= f.select :account_id, options_from_collection_for_select( Account.all,
:id, :name ), :prompt => 'Select Account' %>
<%= f.fields_for :product do |product_form| %>
<%= product_form.check_box :id %>
<% end %>
<%= f.submit %>
<% end %>