collection_select内容未显示

时间:2017-12-16 05:28:09

标签: ruby-on-rails ruby

我目前正在尝试通过 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

这是 contact / 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 %>

这是 contact / 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

提前谢谢你:)

修改: 通过Rails c命令添加了 Contacts#Show 方法和 Contact.find(2).organization

添加 routes.rb

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

有两个问题:

  1. 您无法将组织保存到合同中。 您可以通过Contact.find(2).organizations登记we can Auto save form using Ajax function AutoSaveMyForm(spanid) { var dataToPost = $("form").serialize() $.ajax({ type: "POST", url: "/MyController/AutoSaveActionMethod", data: dataToPost, cache: false, success: function(resultdata) { if (resultdata['Code'] == '1') { // show success saved console.log(resultdata['ResultMsg']); if (spanid == "SaveLastStep") { window.location = "/Dashboard/Index"; } $('#' + spanid).html('Save Successfully.'); } else if (resultdata['Code'] == '0') { // show error console.log(resultdata['ResultMsg']); $('#' + spanid).html('Not Saved'); } else { // an error has occured $('#' + spanid).html('Error Generated.'); } } }); } window.setInterval(function() { AutoSaveMyForm('SpanIdToShowResult') }, 60000); // 1 min By using set interval method we can call javascript method which call ajax to save form and pass any span id to get result back
  2. 我们从不使用私有方法编写新内容和创建。
  3. 您的私人方法不应包含任何凝乳。

    app / controllers / contacts_controller.rb

    rails c

    app / views / contact / new.html.erb

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

答案 2 :(得分:0)

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

尝试添加contact_controller

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

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

我希望这对你有所帮助。