如何在控制器中的动作内使用数组变量

时间:2012-04-09 05:06:41

标签: ruby-on-rails arrays ruby-on-rails-3 model-view-controller controller-action

我想获取那些与当前用户同一所大学的用户发布的所有帖子......所以在我的欢迎控制器中我写了以下代码..


class WelcomesController < ApplicationController

def index

  @col = Education.select(:college_id).where(:user_id => @current_user)
  @user = Education.select(:user_id).where(:college_id => @col)
  @welcome = Welcome.where(:user_id => @user)

end

end

以下是欢迎和教育模式的shema代码:

create_table "welcomes", :force => true do |t|
    t.text     "message"
    t.integer  "user_id"
end

create_table "educations", :force => true do |t|
    t.integer  "college_id"
    t.integer  "user_id"
end

@col = Education.select(:college_id).where(:user_id => @current_user) .... 此行返回与当前登录用户相关联的大学ID。这在我的控制台上完美运行,该控制台在输出后返回..

[#<Education college_id: 1>, #<Education college_id: 2>]

但我不知道如何在我的下一行使用此输出,所以我写了这个语句,它应该返回所有用户的大学id是流行语句的输出

@user = Education.select(:user_id).where(:college_id => @col)

,我的最后一行应该返回其ids在@user数组中的用户发布的所有帖子:

 @welcome = Welcome.where(:user_id => @user)

但这不起作用。当我运行我的项目时,我无法在我的页面和控制台上看到任何输出我得到以下输出: SELECT welcomes。* FROM welcomes WHERE(welcomesuser_id IN(NULL)) 这意味着它没有得到任何用户ID .. 我该如何解决这个问题......

3 个答案:

答案 0 :(得分:0)

你可以试试这个:

@col = Education.select(:college_id).where(:user_id => @current_user.id).all
@users = Education.select(:user_id).where(:college_id => @col.collect(&:college_id)).all
@welcome = Welcome.where(:user_id => @users.collect(&:user_id)).all

答案 1 :(得分:0)

我认为实现此目的的最佳方式是在用户和教育模型之间建立has_many_and_belongs_to_many关系。 (每个Education都有很多用户,每个用户可能有多个Eductions。)您需要在数据库中创建一个连接表来支持这种类型的关系 - 有关详细信息,请参阅Rails Guide

我会以这种方式设置你的模型:

class User < ActiveRecord::Base
  has_one :welcome
  has_and_belongs_to_many :educations
end

class Education < ActiveRecord::Base
  has_and_belongs_to_many :users
end

class Welcome < ActiveRecord::Base
  belongs_to :user
end

has_many_and_belongs_to_many连接表迁移的连接表(请务必仔细检查此代码,不确定我是否完全正确):

def self.up
  create_table 'education_user', :id => false do |t|
    t.column :education_id, :integer
    t.column :user_id, :integer
  end
end

您的控制器代码现在变得更加简单,如下所示:

@welcomes = @current_user.eductions.users.welcome.all

在您看来:

<% @welcomes.each do |welcome| %>
  <p><%= welcome.message %></p>
<% end %>

Ruby on Rails的一个更强大的功能是模型关系。他们在前面做了一些工作,但如果你花时间正确设置它们,它们可以让你的生活更轻松,正如上面简化的@welcomes查询所证明的那样。

答案 2 :(得分:0)

我建议你在用户和拼贴之间建立关系

class User < ActiveRecord::Base
  has_many :educations
  has_many :colleges, :through => :educations
  has_many :posts

  scope :by_college_id, lambda {|cid| where("exists (select educations.id from educations where educations.user_id = users.id AND educations.college_id in (?) limit 1)", Array.wrap(cid)) }

  def college_mates
    self.class.by_college_id(self.college_ids).where("users.id != ?", id)
  end :through => :educations
end

class Education < ActiveRecord::Base
  belongs_to :user
  belongs_to :college
end

所以现在在你的控制器中你可以写

class WelcomesController < ApplicationController
  def index
    @posts = @current_user.college_mates.includes(:posts).map(&:posts).flatten
    # or
    @posts = Post.where(user_id: @current_user.college_mates.map(&:id))
  end
end

第二个变体生成3个sql请求,第一个变体 - 只有两个。但这与数据相同,我认为时间也一样。通常控制器只包含几行代码,所有逻辑都写在模型中。理想情况下,控制器应仅包含Post.by_college_mates_for(@curren_user.id)