Rails ActiveRecord id = xyz有效但id!= xyz不起作用

时间:2013-07-15 20:11:18

标签: ruby-on-rails ruby-on-rails-3.2 has-and-belongs-to-many

这有效:

@user = User.find(current_user.id)
@users_cities = @user.cities

这不起作用:

@other_users = User.where("id != ?", 1)
@users_cities = @other_users.cities

但是,我可以从控制台运行第二个示例,它可以正常工作。

这是错误:

NoMethodError in CitiesController#index
undefined method `cities' for #<ActiveRecord::Relation:0x007f8f670f2870>
app/controllers/cities_controller.rb:23:in `index'

第23行就是这个:

@users_cities = @other_users.cities

模型只是has_and_belongs_to_many :citieshas_and_belongs_to_many :user。我认为has_and_belongs_to_many :user本来是has_and_belongs_to_many :users但是我得到了同样的错误(即使重新启动服务器后也是如此)。

3 个答案:

答案 0 :(得分:4)

.first添加到ActiveRecord::Relation对象

@other_users = User.where("id != ?", 1).first
@users_cities = @other_users.cities

User.find_by_id(1)User模型的实例。

User.where(:id => 1)不是User模型,而是ActiveRecord::Relation

答案 1 :(得分:1)

在前一种情况下,它工作正常,因为 @user 指向 userobject 。假设您的用户模型具有以下属性(id,name,created_at,updated_at)。

@user= User.find(current_user.id)
@user.class
 => User(id: integer, name: string, created_at: datetime, updated_at: datetime, etc)
@user
  => #<User id: 1, name: "Amar",created_at: "2013-07-10 10:07:37", updated_at: "2013-07-10 10:07:37"> 

现在您的实例变量 @user 指向 userobject ,因此以下工作正常。

@users_cities = @user.cities 

但是在其中的情况下,它是一种关系,而实例变量包含数组,其单条记录

@user= User.where(:id => current_user.id)
@user.class
  => ActiveRecord::Relation
@user
  => [#<User id: 1, name: "Amar", created_at: "2013-07-10 10:07:37", updated_at: "2013-07-10 10:07:37">] 

此处, @user 未指向 userobject ,因此您无法获得与该用户相关的城市。您可以尝试以下方法。

@user= User.where(:id => current_user.id).first #first gets the first object from the array.
@user.class
 => User(id: integer, name: string, created_at: datetime, updated_at: datetime, etc)
@user
 => #<User id: 1, name: "Amar",created_at: "2013-07-10 10:07:37", updated_at: "2013-07-10 10:07:37"> 

在这种情况下,以下情况应该有效,因为您的实例变量 @user 已使用第一个指向单个用户对象。 / p>

@users_cities = @user.cities 

再次在您的情况下,您正在从用户模型中获取数组

@other_users = User.where("id != ?", 1)

它将收集一系列元素。所以你必须迭代数组才能找到它的城市。

@other_users.each do |user|
 # do manipulation with user.cities
end

在这种情况下,如果您使用第一个,那么它将仅指向数组中的第一个对象通过迭代覆盖所有其他用户

答案 2 :(得分:0)

@other_users返回用户数组而不是单个用户对象。您需要遍历所有对象以获取城市

使用地图

  

@users_cities = @ other_users.map(&amp;:cities)=&gt; [[city1,city 2],[city3,city4]]

如果你想要一个平面数组,那么用户flattern

  

@users_cities = @ other_users.map(&amp ;: cities).flatten

另一种选择是从城市模型中选择城市而不是通过关联。

之类的东西
  

@users_cities = City.where(“user_id!= 1”)