сохранение записи в таблицу Has_many: через - PullRequest
0 голосов
/ 17 октября 2011

Я новичок в Rails 3 и у меня проблемы с сохранением записей в таблице Join.Я искал и пробовал разные примеры, найденные на этом сайте и из документации или книг, но я не понимаю, почему я не могу заставить его работать.Я пытаюсь создать авторизацию, создавая роли и связывая их с пользователями.До сих пор я пытался назначить роли из действия обновления в контроллере Users без преобладания.

У меня есть 3 модели: User.rb, role.rb и assignment.rb (таблица соединений)

class User < ActiveRecord::Base
  has_many :assignments, :dependent => :destroy
  has_many :roles, :through => :assignments, :foreign_key => :role_id
  accepts_nested_attributes_for :roles
  attr_accessor :password, :role_ids
  attr_accessible :first_name, :last_name, :email, :password, :password_confirmation, :status, :description, :username, :roles_attributes
  ...
end

class Role < ActiveRecord::Base
  has_many :assignments
  has_many :users, :through => :assignments, :foreign_key => :user_id
  accepts_nested_attributes_for :users
  attr_accessible :name
end

class Assignment < ActiveRecord::Base
  belongs_to :user
  belongs_to :role
  accepts_nested_attributes_for :roles
end  

Контроллер пользователей в действии обновления У меня есть следующие

class UsersController < ApplicationController
  ...
  def update
    @user = User.find(params[:id])
    if @user.update_attributes(params[:user])
      @user.roles.build
      flash[:success] = "Profile updated"
      redirect_to @user
    else
      @title = "Edit" + " " + @user.username
      render 'edit'
    end
  end
  ...
end

и на странице просмотра «Изменить» я хочу установить флажки для обновления записи пользователя с соответствующей ролью:

РЕДАКТИРОВАТЬ: Изменен флажок «check_box»с "check_box_tag" ... флажки появляются правильно, но значения не сохраняются.

<%= form_for(@user) do |f| %>
  ...
  <div class="field">
     <%= f.label :roles %><br />
     <%= f.fields_for :role_ids do |r| %>
       <% @roles.each do |role| %>
         <%= check_box_tag "user[roles][]", role.id, @user.roles.include?(role.id) %>   
         <%= role.name %>   
       <% end %>
       <%= hidden_field_tag "user[roles][]", "" %>
     <% end %>
  </div>
<% end %>

С этим кодом я даже получаю сообщение об ошибке, когда «Роли» не связаны.

РЕДАКТИРОВАТЬ: это было исправлено с accepts_nested_attributes_for :role.Спасибо!

Не найдено связи для имени `role '.Это уже определено?

Я действительно смущен, когда делаю что-то не так.Ваша помощь будет высоко ценится.

Aurelien

Ответы [ 2 ]

2 голосов
/ 17 октября 2011

Вы должны использовать то же имя с «accepts_nested_attributes_for», что и при определении ассоциации:

class Assignment < ActiveRecord::Base
  belongs_to :user
  belongs_to :role
  accepts_nested_attributes_for :role
end 
0 голосов
/ 18 октября 2011

Наконец-то решил проблемы и подумал, что смогу поделиться.

Ассоциации моделей, но я изменил attr_accessible:

class User < ActiveRecord::Base
  has_many :assignments, :dependent => :destroy
  has_many :roles, :through => :assignments, :foreign_key => :role_id
  accepts_nested_attributes_for :roles
  attr_accessor :password
  attr_accessible ..., :roles_ids
  ...
end

В пользовательском контроллере для действия редактирования и обновления.

def edit
  @title = "Edit" + " " + @user.username
  @roles = Role.find(:all)
  @user.assignments.build
end

def update
  @user = User.find(params[:id])
  if @user.update_attributes(params[:user])
    flash[:success] = "Profile updated"
    redirect_to @user
  else
    @title = "Edit" + " " + @user.username
    render 'edit'
  end
end

Важной частью была часть просмотра и присвоение правильных имен тэгам-флажкам

<%= form_for(@user) do |f| %>
  <div class="field">
  <%= f.label :roles %><br />
  <%= f.fields_for :role_ids do |r| %>
    <% @roles.each do |role| %>
      <%= check_box_tag "user[role_ids][]", role.id, @user.roles.include?(role) %>  
      <%= role.name %>  
    <% end %>
    <%= hidden_field_tag "user[role_ids][]", @user.id %>
  <% end %>
</div>

check_box_tag позволяет форме сохранять массив и дает больше контроля, чем check_box Затем, чтобы назначить несколько идентификаторов ролей, имя check_box_tag должно включать user[roles_ids][]. Наконец, последний параметр check_box_tag возвращается, если у пользователя уже есть роли, и проверяет флажки, если оно истинно.

Я должен признать, что часть имени check_box_tags действительно сбивает с толку, но она работает:).

...