Question

I want to fetch all posts posted by those users who have gone to same college as the current users...So inside my welcome controller i have written following code..


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

Following is my shema code for welcome and education model:

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)....this line returns college ids associated with current logged in user.This is working perfectly on my console which is returning following output..

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

but i dont know how to use this output in my next line,so i have written this statement which should return all the users whose college id is the output of prevous statement

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

and my last line should return all the posts posted by those users whose ids are inside the @user array:

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

but this is not working.When i run my project i cant see any output on my page and on console i am getting following output : SELECT welcomes.* FROM welcomes WHERE (welcomes.user_id IN (NULL)) which means its not getting any user ids.. How can i solve this ...

Était-ce utile?

La solution

You can try this:

@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

Autres conseils

The best way I see to accomplish this is to set up a has_many_and_belongs_to_many relationship between your User and Education models. (Each Education will have many Users and each User may have multiple Eductions.) You will need to create a joining table in your database to support this type of relationship - see the Rails Guide for more information on this.

I would set up your models in this manner:

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

The join table for the has_many_and_belongs_to_many join table migration (be sure to double check this code, not sure I got this exactly right):

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

Your controller code is now much simpler and looks like this:

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

In your view:

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

One of the more powerful features of Ruby on Rails is the model relationships. They are a little more work up front, but if you take the time to set them up correctly they can make your life much easier, as is evidenced by the simplified @welcomes query above.

I'd recommend you to make relation between User and Collage

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

So now in your controller you can write

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

Second variant generates 3 sql-requests, first variant - only two. But this is same work with data, I think time will be also same. Usually controllers contain only few lines of code, all logic written in models. Ideally controller should contain only Post.by_college_mates_for(@curren_user.id)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top