collection_select内容未显示

问题描述 投票:0回答:3

我目前正在尝试通过collection_select表单显示内容标识自己的组织。

问题是在创建新联系人并选择组织之后。组织不显示。

到目前为止,我已经尝试在网上搜索答案,但没有任何帮助。我也尝试过我能想到的所有问题都是我的代码问题。

这是我的模特:

class Contact < ApplicationRecord
has_many :contact_orgs
has_many :organizations, through: :contact_orgs
accepts_nested_attributes_for :organizations
end

class Organization < ApplicationRecord
has_many :contact_orgs
has_many :contacts, through: :contact_orgs
end

class ContactOrg < ApplicationRecord
belongs_to :contact
belongs_to :organization
accepts_nested_attributes_for :organization
end

这是我的schema.rb:

create_table "contact_orgs", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "contact_id"
t.integer "organization_id"
t.index ["contact_id"], name: "index_contact_orgs_on_contact_id"
t.index ["organization_id"], name: "index_contact_orgs_on_organization_id"
end

create_table "contacts", force: :cascade do |t|
t.string "first_name"
t.string "last_name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end

create_table "organizations", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "industry"
end

这是我的contact_controller.rb:

private
def contact_params
params.require(:contact).permit(:first_name, :last_name, 
organizations_attributes: [:name, :industry])
end

def new
@contact = Contact.new
end

def show
@contact = Contact.find(params[:id])
end

def create
@contact = Contact.new(contact_params)
if @contact.save
redirect_to @contact
else
render 'new'
end
end

这是我的联系人/ new.html.erb:

<%= form_with scope: :contact, url: contact_path, local: true do |form| %>

<p>
<%= form.label :first_name %><br>
<%= form.text_field :first_name %>
</p>

<p>
<%= form.label :last_name %><br>
<%= form.text_field :last_name %>
</p>

<p>
<%= form.label :organization_id, "Organization:" %><br>
<%= form.collection_select :organization_id, Organization.order(:name), :id, :name, {}, {multiple: true} %>
</p>

<p>
<%= form.submit %>
</p>
<% end %>

这是我的联系人/ show.html.erb:

<p>
<strong>First name:</strong>
<%= @contact.first_name %>
</p>

<p>
<strong>Last Name:</strong>
<%= @contact.last_name %>
</p>
<hr>

<p>
<strong>Organizations:</strong>
<ul>
<% @contact.organizations.each do |organization| %>
<li><%= organization.name %></li>
<% end %>

</ul>
</p>

这是我刷新localhost:3000 / contact / 2页面时我的Rails服务器所说的内容。

Here is what my Rails Server is saying when I refresh my localhost:3000/contact/2 page.

这是我的Rails控制台中的内容:

2.4.1 :001 > Contact.find(2).organizations
Contact Load (0.2ms)  SELECT  "contacts".* FROM "contacts" WHERE "contacts"."id" = ? LIMIT ?  [["id", 2], ["LIMIT", 1]]
Organization Load (0.2ms)  SELECT  "organizations".* FROM "organizations" INNER JOIN "contact_orgs" ON "organizations"."id" = "contact_orgs"."organization_id" WHERE "contact_orgs"."contact_id" = ? LIMIT ?  [["contact_id", 2], ["LIMIT", 11]]=> #<ActiveRecord::Associations::CollectionProxy []> 

这是我的routes.rb文件:

Rails.application.routes.draw do
get 'welcome/index'

resources :contacts, :organizations

root 'welcome#index'
end

提前谢谢你:)

编辑:添加联系人#显示方法和Contact.find(2).organization via Rails c命令。

添加了routes.rb

ruby-on-rails ruby
3个回答
1
投票

由于您正在使用连接表(ContactOrg),因此在创建ContactOrg时,您确实尝试创建新的Contact记录,而不是将其分配给Organization,这是您的代码读取的方式。

编辑

虽然我上面的第一个声明仍然有一点点的优点(你实际上是在创建一个连接记录),但你绝对可以让rails帮助你,你的原始答案非常接近。这里只是有更新的代码,我试图突出显示更改。

应用程序/模型/ contact.rb

class Contact < ApplicationRecord
  has_many :contact_orgs
  has_many :organizations, through: :contact_orgs

  accepts_nested_attributes_for :organizations # you were correct here
end

应用程序/视图/接触/ new.html.erb

<%= form_with model: :contact, local: true do |form| %>
  # use :model here so you can ultimately use this form for both new and edit.
  # The model method will infer the correct path

  ... contact fields here as you have them ...

  <p>
    <%= form.collection_select :organization_ids, Organization.order(:name), :id, :name, {}, {multiple: true} %>
    # the attribute for organization_id should be plural because you're accepting multiple
  <p>

  <p>
    <%= form.submit %>
  </p>
<% end %>

应用程序/控制器/ contacts_controller.rb

class ContactsController < ApplicationController


  ... new, show, and create as you have them ...

   private # private methods should go after all public methods 

   def contact_params
     params.require(:contact).permit(:first_name, :last_name, organization_ids: [])
     # again, the attribute you're passing in is called organization_ids, and you give it an empty array
   end
end

0
投票

你的contract_controller没有初始化show.html.erb中使用的@contact,因为没有任何show方法。

尝试添加contact_controller

def show
  @contact = Contact.find(param[:id])
end

PS:当你调用show方法时,一定要传递给contact.id

我希望这对你有帮助。


0
投票

有两个问题:

  1. 您无法将组织保存到合同中。您可以通过Contact.find(2).organizations登记您的rails c
  2. 我们从不使用私有方法编写new和create。

您的私人方法不应包含任何凝乳。

在你的app / controllers / contacts_controller.rb中

private

def contact_params
  params.require(:contact).permit(
    :first_name, 
    :last_name, 
    organizations_attributes: [
      :name, 
      :industry
    ]
 )
end

在您的app / views / contact / new.html.erb中

<%= form_with scope: :contact, url: contact_index_path, local: true do |form| %>

  <p>
    <%= form.label :first_name %><br>
    <%= form.text_field :first_name %>
  </p>

  <p>
    <%= form.label :last_name %><br>
    <%= form.text_field :last_name %>
  </p>

  <p>
    <%= form.fields_for :organizations do |o| %>
      <%= o.label :organization %><br>
      <%= o.collection_select(:organization_id, Organization.all,
                          :id, :org_name,
                          {:prompt => 'Please select the organization'}) %>
  </p>

  <p>
    <%= form.submit %>
  </p>
<% end %>
© www.soinside.com 2019 - 2024. All rights reserved.