我已经做了a github repo that you can find here只是为了这个问题。我有 3 个型号:
class User < ActiveRecord::Base
has_many :user_countries
has_many :event_countries,
-> { where(user_countries: {:event => true}) },
:through => :user_countries,
:source => :country
has_many :research_countries,
-> { where(user_countries: {:research => true}) },
:through => :user_countries
:source => :country
end
class UserCountry < ActiveRecord::Base
belongs_to :country
belongs_to :user
end
class Country < ActiveRecord::Base
# ...
end
因此用户应该能够选择 event_countries 和 Research_countries。
这是我的用户 Controller (没什么复杂的):
class UsersController < ApplicationController
respond_to :html, :json
before_action :get_user, only: [:show, :edit, :update]
before_action :get_users, only: [:index]
def index
end
def show
end
def edit
end
def update
@user.update_attributes(user_params)
respond_with @user
end
private
def get_user
@user = User.find(params[:id])
end
def get_users
@users = User.all
end
def user_params
params.require(:user).permit(:first_name, :event_countries => [:id, :name])
end
end
这是我的用户显示页面:
<%= best_in_place @user, :first_name %>
<p> event countries: </p>
<%= best_in_place @user, :event_countries, place_holder: "click here to edit", as: :select, collection: Country.all.map {|i| i.name} %>
<%= link_to "users index", users_path %>
所以这里真的没有什么复杂的。我还可以成功编辑我的用户名字,best_in_place 工作正常。
问题是:如何编辑 event_countries ?正如您所看到的,我尝试对国家/地区使用收集选项,但是当我尝试选择一个国家/地区时,我得到以下信息:
Processing by UsersController#update as JSON
Parameters: {"user"=>{"event_countries"=>"3"}, "authenticity_token"=>"l5L5lXFmJFQ9kI/4klMmb5jDhjmtQXwn6amj1uwjSuE=", "id"=>"6"}
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 6]]
(0.1ms) begin transaction
(0.1ms) rollback transaction
Completed 500 Internal Server Error in 3ms
NoMethodError (undefined method `each' for nil:NilClass):
app/controllers/users_controller.rb:17:in `update'
我不明白它在做什么,我知道这一定是集合选项的问题。如果您需要查看任何文件,请在此处查看我的存储库: https://github.com/spawnge/best_in_place_join_models_twice 。我在这个问题上花了很多时间,任何答案/建议将不胜感激:)
更新:
我已经尝试过这个:
<%= best_in_place @user, :event_country_ids, as: :select, collection: Country.all.map { |i| i.name }, place_holder: "click here to edit", html_attrs: { multiple: true } %>
我已将 :event_country_ids 添加到我的用户参数中:
params.require(:user).permit(:first_name, :event_country_ids)
现在我可以看到所有国家/地区,但是当我选择一个国家/地区时,我会得到以下结果:
Started PUT "/users/3" for 127.0.0.1 at 2014-12-18 01:19:27 +0000
Processing by UsersController#update as JSON
Parameters: {"user"=>{"event_country_ids"=>"1"}, "authenticity_token"=>"aZAFIHgzdSL2tlFcGtyuu+XIJW3HX2fwQGHcB9+iYpI=", "id"=>"3"}
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 3]]
(0.0ms) begin transaction
Country Load (0.0ms) SELECT "countries".* FROM "countries" WHERE "countries"."id" = ? LIMIT 1 [["id", 1]]
Country Load (0.0ms) SELECT "countries".* FROM "countries" INNER JOIN "user_countries" ON "countries"."id" = "user_countries"."country_id" WHERE "user_countries"."event" = 't' AND "user_countries"."user_id" = ? [["user_id", 3]]
SQL (0.1ms) DELETE FROM "user_countries" WHERE "user_countries"."user_id" = ? AND "user_countries"."country_id" = 2 [["user_id", 3]]
SQL (0.0ms) INSERT INTO "user_countries" ("country_id", "event", "user_id") VALUES (?, ?, ?) [["country_id", 1], ["event", "t"], ["user_id", 3]]
(20.9ms) commit transaction
Completed 204 No Content in 28ms (ActiveRecord: 21.3ms)
正如您所看到的,它似乎插入了正确的内容: INSERT INTO "user_countries"("country_id", "event", "user_id") VALUES (?, ?, ?) [["country_id", 1], ["event", "t"], ["user_id", 3]]
但是,紧接着我就收到了 Completed 204 No Content 。我不明白当我刷新页面时输入为空。有什么建议吗?
更新2:
我检查了控制台,它可以工作,我可以将 event_countries 添加到用户。但是,当我刷新页面时,它不会显示用户的 event_countries,我想那是因为我正在使用 event_country_ids 对象。
最佳答案
我认为以下代码应该有效:
<%= best_in_place @user, :event_country_ids, as: :select,
collection: Country.all.each_with_object({}) { |i, memo| memo[i.id] = i.name },
place_holder: "click here to edit",
html_attrs: { multiple: true } %>
假设您希望用户能够分配多个 event_countries
。
引用
- http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many ,特别是由
has_many
创建的collection_singular_ids=
方法。 - https://github.com/bernat/best_in_place#select ,集合的结构需要是哈希。对于每个
key => value
对,键是随表单提交的内容,值是向用户显示的内容。 - http://ruby-doc.org/core-2.1.5/Enumerable.html#method-i-each_with_object ,
each_with_object
是核心 Ruby 库的一部分。
关于ruby-on-rails - best_in_place 在 Rails 4 中具有多对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27528990/