【问题标题】:rails has_one through formrails has_one 通过表单
【发布时间】:2016-06-04 17:49:12
【问题描述】:

管理员.rb:

class Administrator < ActiveRecord::Base
    has_one :administrator_role, dependent: :destroy
    has_one :role, through: :administrator_role
end

角色.rb:

class Role < ActiveRecord::Base
    has_many :administrator_roles
    has_many :administrators, through: :administrator_roles
end

管理员角色.rb:

class AdministratorRole < ActiveRecord::Base
    belongs_to :administrator
    belongs_to :role
end

在“新”操作 administrator_controller 的视图中:

<%= form_for @administrator do |f| %>
  <%= render 'shared/errors', object: @administrator %>

  <div class="form-group">
    <%= f.label :role_id, "Роль:" %>
    <%= f.collection_select(:role_id, @roles, :id, :name) %>
  </div>
...
  <%= f.submit 'Save', class: 'btn btn-primary btn-lg' %>
<% end %>

administrator_controller.rb:

class AdministratorsController < ApplicationController
  def new
    @administrator = Administrator.new
    @roles = Role.all
  end

  def create
    @administrator = Administrator.new(administrators_params)
    if @administrator.save
      flash[:success] = "Account registered!"
      redirect_to root_path
    else
      render :new
    end
  end

...
  private

  def administrators_params
    params.require(:administrator).permit(:login, :password, :password_confirmation, :role_id)
  end
end

当你打开页面时得到错误:

undefined method `role_id' for #<Administrator:0x007f6ffc859b48>
Did you mean?  role

如何解决?如果我在 role_id 中放置了一个角色,当你创建管理员时会得到错误:

ActiveRecord::AssociationTypeMismatch (Role(#69964494936160) expected, got String(#12025960)):

【问题讨论】:

    标签: ruby-on-rails activerecord relationship


    【解决方案1】:

    你必须重写表格如下:

    <%= form_for @administrator do |f| %>
      <%= render 'shared/errors', object: @administrator %>
    
      <div class="form-group">
        <%= f.fields_for :role do |role_form| %
          <%= role_form.label :role_id, "Роль:" %>
          <%= role_form.select(:id, @roles.map { |role| [role.name, role.id] }) %>
        <% end %>
      </div>
    ...
      <%= f.submit 'Save', class: 'btn btn-primary btn-lg' %>
    <% end %>
    

    您还需要添加 1 行来启用嵌套表单逻辑:

    class Administrator < ActiveRecord::Base
        has_one :administrator_role, dependent: :destroy
        has_one :role, through: :administrator_role
        accepts_nested_attributes_for :role
    end
    

    并且还可以更改控制器,例如:

    class AdministratorsController < ApplicationController
    
      #....
    
      private
    
      def administrators_params
        params.require(:administrator).permit(
          :login, :password,
          :password_confirmation,
          role_attributes: [ :id ]
        )
      end
    end
    

    当你使用has_one关联时,你会得到下面的方法,但不是association_id=,这就是错误的意思。

    association(force_reload = false)
    association=(associate)
    build_association(attributes = {})
    create_association(attributes = {})
    create_association!(attributes = {})
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-05
      • 1970-01-01
      相关资源
      最近更新 更多