ruby-on-rails - rails has_one 通过表单

标签 ruby-on-rails activerecord relationship

管理员.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

查看"new"操作 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)):

最佳答案

您必须按如下方式重写表单:

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

并且还更改 Controller ,如:

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 = {})

关于ruby-on-rails - rails has_one 通过表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37633287/

相关文章:

ruby-on-rails - 在 Rails 中设置公共(public)文件类型的内容处置?

mysql - 带有命名空间的模型 - 错误的表名(没有命名空间)

ruby-on-rails - 在 osx 10.9.3 上使用 RVM 安装 ruby​​-1.9.3-p547 时出错

mysql - 创建 N :M relationship in SQLite

php - 没有模型的 Eloquent 关系

MySQL相关数据库的删除顺序?

ruby-on-rails - Rails 路由匹配查询参数

ruby-on-rails - PG::UndefinedTable:错误:使用 SELECT DISTINCT ON 时缺少表的 FROM 子句条目

sql - SQLite 与 Postgres 中的 Rails Active Record 组查询

ruby-on-rails - Rails 预加载问题 Find( :all, :include => [:model])