【问题标题】:Rails 4: form_for with associationsRails 4:带关联的 form_for
【发布时间】:2016-03-09 15:23:19
【问题描述】:

Rails 和 Ruby 的新手。与form_for 和关联作斗争。我正在尝试设置一个允许用户从客户端列表中进行选择的 rails 应用程序。客户端通过has_many :through 关系关联。我的模型按预期工作,我可以通过 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 %>

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4


    【解决方案1】:

    首先,看看那个宝石:Nested Form。这里还有几个关于这个主题的railscasts。但是,如果您愿意构建自己的解决方案,可以先阅读有关嵌套属性的文档here

    希望对你有帮助!

    更新。关于你的路线和一切。

    resources :clients do
      resources :users
    end
    
    resources :users do
      resources :clients
    end 
    

    您已在此处嵌套资源。就像您在评论中提到的那样,users/:user_id/clients/newclients/new 将导致相同的操作。这就是此路由的工作方式。您对 Rails 做事风格的看法是正确的 - 在控制器中进行一些可怕的逻辑检查并基本上在一个操作中执行不同的操作,这是非常糟糕的。由于您的操作(将用户与现有客户端关联)与一组标准的 RESTful 操作相距甚远(但最接近的变体将是 update),因此您需要为您的资源引入新操作 - 例如 assign_client。你可以这样做:

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

    您可以以任何您喜欢的动作呈现表单。但是,如果您想要更多独立的东西,您可以创建一对操作(例如editupdate 对)。第一个将呈现适当的表单,第二个将在服务器上处理该表单。

    【讨论】:

    • 感谢您的回复。我仍在尝试了解如何管理向用户添加新的客户端关联。在我上面的示例中,路由 /clients/new 和路由 /users/1/clients/new 都被路由到客户端控制器的“创建”方法。但是,我希望 /clients/new 用于创建新的客户记录,而 /users/1/clients/new 用于在用户和现有客户之间创建新的关联。我可以在“create”方法中对此进行测试,但是我不确定这是否是此类活动的“rails”约定。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-05
    • 2014-09-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多