ruby-on-rails – Rails 4:form_for with associations

新的铁轨和ruby.与form_for和协会一起苦苦挣扎.我正在尝试设置一个rails应用程序,允许用户从客户列表中进行选择.客户端通过has_many关联:通过关系.我让模型按预期工作,我可以通过rails控制台将用户添加到用户.我现在想将此功能移动到Web界面.下面的代码是我尝试过的,但它对我来说没有意义.我不确定哪个控制器动作是正确的动作.我应该在客户端的创建操作中处理表单POST吗?我实际上并不想创建新客户端,我只是希望用户从现有客户端列表中进行选择并创建关联.

我的模型如下:

class Client < ActiveRecord::Base
has_many :users, :through => :user_clients
has_many :user_clients, :dependent => :destroy
end

class User < ActiveRecord::Base
has_many :clients, :through => :user_clients
has_many :user_clients, :dependent => :destroy
end

class UserClient < ActiveRecord::Base
belongs_to :user
belongs_to :client
end

路线如下

resources :clients do
  resources :users
end

resources :users do
  resources :clients
end 

客户端控制器

class ClientsController < ApplicationController
  before_action :set_client, only: [:show, :edit, :update, :destroy]

  def index
    if params[:user_id]
      @clients = User.find_by_id(params[:user_id]).clients
    else
      @clients = Client.all
    end
    @clients
  end

  def create
    if params[:user_id]
      user = User.find(params[:user_id])
      client = Client.find_by_id(params[:client_id])
      user.clients << client
      user.save
      redirect_to users_url
    else
      @client = Client.new(client_params)
      @client.save
      redirect_to clients_url
    end
  end
end

在客户端视图中表单

<h1>new.html.erb</h1>
<% if params[:user_id] %>
  <%= form_for([@user,@client]) do |f| %>
  <div class="field">
    <%= f.label :id %><br>
    <%= f.text_field :id %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
  <% end %>
<% else %>
  <%= render 'form' %>
<% end %>
最佳答案
首先,看看那个宝石:Nested Form.这里还有一些关于这个主题的railscasts.但是,如果您愿意构建自己的解决方案,可以先阅读有关嵌套属性here的文档.

希望能帮助到你!

更新.关于您的路线和一切.

resources :clients do
  resources :users
end

resources :users do
  resources :clients
end 

你在这里嵌套了资源.就像您在评论中提到的那样,users /:user_id / clients / new和clients / new将导致相同的操作.这就是这种路由的工作方式.你对Rails的做事风格是正确的 – 在控制器中进行一些可怕的逻辑检查是非常糟糕的,并且基本上在一个动作中做了不同的事情.由于您的操作(将用户与现有客户端相关联)远离标准的RESTful操作集(尽管最近的变体将会更新),因此您需要为资源引入新操作 – 例如assign_client.你可以这样做:

resources :users do
  resources :clients
  member do
    put :assign_client
  end
end

您可以在任何您喜欢的动作中渲染表单.但是,如果您想要更独立的东西,您可以创建一对动作(类似于编辑和更新对).第一个将呈现适当的表单,第二个将在服务器上处理该表单.

转载注明原文:ruby-on-rails – Rails 4:form_for with associations - 代码日志