【问题标题】:best_in_place with a many to many relationship in rails 4在rails 4中具有多对多关系的best_in_place
【发布时间】:2014-12-17 15:25:44
【问题描述】:

我为这个问题制作了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。

这是我的用户控制器(没什么复杂的):

 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 对象。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 activerecord best-in-place


    【解决方案1】:

    我认为下面的代码应该可以工作:

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

    参考

    【讨论】:

    • 嗨@ColetranePass 非常感谢您的回答,这很有意义。我完全按照你说的做了,但我收到了这个奇怪的错误:syntax error, unexpected =&gt;, expecting '}' ...h_with_object({}) { |i| i.id =&gt; i.name }, place_holder: "cli... ... ^。老实说,我没想到会出现语法错误。怎么了?顺便问一下,你确定the each_with_object method isn't deprecated in Rails 4 吗?如果是这样,有什么替代方案?再次感谢
    • 在这个问题中,他们使用了 each_with_index 方法。我不知道这是否有帮助:stackoverflow.com/questions/21184592/…
    • 对那个语法错误感到抱歉。我编辑了答案以反映正确的语法,并提供了 each_with_object 的 Ruby 核心文档的链接。我不确定为什么它在您提供的链接中被标记为已弃用,因为它肯定在 Ruby 核心库中。
    • 我试过了(使用:memo[:id]),但还是不行。我得到ActiveRecord::RecordNotFound (Couldn't find Country with 'id'=0)。当我点击输入时,我只看到 1 个国家,我无法选择它。你能检查我的问题更新吗?我已经尝试收集:Country.all.map { |i| i.name } 与 event_country_ids 对象,它正在工作。它会更改用户的 event_countries,但是当我刷新页面时,best_in_place 输入不会加载 event_countries。我仍然可以将其仅用作输入,然后使用一些 javascript 重新加载页面。
    • 对不起,又是我的错,应该是memo[i.id]。至于显示国家/地区,我建议探索 best_in_place 提供的display_withhelper_options 选项。将@user.event_countries.pluck(:name) 传递给helper_options 并创建一个辅助方法来显示它们。
    猜你喜欢
    • 2014-02-06
    • 2016-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-14
    • 1970-01-01
    相关资源
    最近更新 更多