2014-02-12 2 views
4

Новые рельсы и рубин. Борьба с form_for и ассоциациями. Я пытаюсь настроить приложение rails, которое позволяет пользователю выбирать из списка клиентов. Клиенты связаны через отношения has_many :through. У меня есть модели, работающие как ожидалось, и я могу добавлять клиентов к пользователям через консоль rails. Теперь я хочу переместить эту возможность в веб-интерфейс. Ниже приведен код, как я пытался, но это просто не имеет смысла для меня. Я не уверен, какое действие контроллера - правильное действие. Должен ли я обрабатывать форму POST в создании действия клиента? Я на самом деле не хочу создавать нового клиента, я просто хочу, чтобы пользователь выбирал из списка существующих клиентов и создавал ассоциацию.Рельсы 4: form_for с ассоциациями

Мои модели заключаются в следующем:

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 %> 

ответ

1

Во-первых, взгляните на этот драгоценный камень: 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 (ближайший вариант будет update, хотя), вам необходимо ввести новое действие для вашего ресурса - например, . Вы можете сделать это следующим образом:

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

Вы можете визуализировать форму в любом действии, которое вам нравится. Однако, если вы хотите что-то еще автономно, вы можете создать пару действий (что-то вроде edit и update пары). Первая будет отображать соответствующую форму, а вторая будет обрабатывать эту форму на сервере.

+0

Благодарим за отзыв. Я все еще пытаюсь понять, как управлять добавлением новой клиентской ассоциации к пользователю. В приведенном выше примере маршрут/клиенты/новый, а также маршрут/users/1/clients/new оба маршрутизируются к методу «create» контроллера клиента. Однако я хотел бы, чтобы/clients/new использовался для создания новой записи клиента и/users/1/clients/new для создания новой связи между пользователем и существующим клиентом. Я могу проверить это в методе «create», однако я не уверен, что это соглашение «rails» для этого вида деятельности. –

Смежные вопросы