简体   繁体   中英

Rails: how to create a form to create a new has_many relationship

I have a User and a Project models that are linked with a has_and_belongs_to_many relationship (each users can be a part of several projects, and they can be the creator of several projects). I want to create a form to add a user to a project. The user would need to enter the username of another user to add him. How can I do that?

Here is what I've tried:

<%= form_for(@project) do |f| %>
    <%= f.label :username, "Username" %>
    <%= f.text_field :users %>
    <%= f.submit "Add" %>
<% end %>

Then in the controller I would do something like this:

def add_user
    @project = Project.find(params[:id])
    user = User.find_by(username: params[:username])
    user.projects << @project
    user.save
    redirect_to @project
  end

The issue is that the text field for the user does not do what I thought it would, it output the @project.users inspect ( #<ActiveRecord::Associations::CollectionProxy::ActiveRecord_Associations_CollectionProxy_User:0x007fc3e98e8d70> ).

I've see the nested forms but I don't think it's appropriate as the user and the project are already created. I'm using rails 4.

The nested forms stuff isn't just for creating new records, you can use it to add to join models, too

I would look at accepts_nested_attributes_for


Accepts Nested Attributes For

I would personally try this:

 #app/controllers/projects_controller.rb
 def new
      @project = Project.new
      @project.projects_users.build
 end

 def create
      @project = Project.new(project_params)
      @project.save
 end

 def edit
      @project = Project.find(params[:id])
 end

 def update
     @project = Project.find(params[:id])
     @project.save
 end

 private
 def project_params
     params.require(:project).permit(:project, :params, projects_users_attributes: [:user_id])
 end

#app/models/project.rb
Class Project < ActiveRecord::Base
    accepts_nested_attributes_for :projects_users
end

#app/views/projects/edit.html.erb
<%= form_for(@project) do |f| %>
    <%= f.fields_for :projects_users %>
        <%= f.label :username, "User ID" %>
        <%= f.text_field :user_id %> #-> can change to <select> later
    <% end %>
    <%= f.submit "Add" %>
<% end %>

Take a look at the cocoon gem. It provides some nested form stuff that would be hard to solve with rails of the shelf functionality. I have used it recently to do something very similar (find or create on M2M relation)

https://github.com/nathanvda/cocoon

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM