【问题标题】:how to use array variables inside action in controller如何在控制器的动作中使用数组变量
【发布时间】:2012-04-09 05:06:41
【问题描述】:

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


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 =&gt; @current_user)....此行返回与当前登录用户关联的大学 ID。这在我的控制台上运行良好,返回以下输出..

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

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

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

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

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

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

【问题讨论】:

  • 使用粗体文本会使事情变得更难阅读,并且人们不再知道什么是重要的,因此避免在长句中使用粗体文本,而是用它来强调真正需要强调的内容。
  • 好的,Zabba 会照顾好你所说的......

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


【解决方案1】:

你可以试试这个:

@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

【讨论】:

    【解决方案2】:

    我认为实现此目的的最佳方法是在用户模型和教育模型之间建立 has_many_and_belongs_to_many 关系。 (每个教育将有许多用户,每个用户可能有多个教育。)您需要在数据库中创建一个连接表来支持这种类型的关系 - 请参阅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 查询所证明的那样。

    【讨论】:

      【解决方案3】:

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

      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)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-04
        • 2017-04-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-22
        相关资源
        最近更新 更多