rails select and include

前端 未结 5 1251
清歌不尽
清歌不尽 2021-02-19 02:02

Can anyone explain this?

Project.includes([:user, :company])

This executes 3 queries, one to fetch projects, one to fetch users for those proje

相关标签:
5条回答
  • 2021-02-19 02:12

    Rails has always ignored the select argument(s) when using include or includes. If you want to use your select argument then use joins instead.

    You might be having a problem with the query gem you're talking about but you can also include sql fragments using the joins method.

    Project.select("name").joins(['some sql fragement for users', 'left join companies c on c.id = projects.company_id'])
    

    I don't know your schema so i'd have to guess at the exact relationships but this should get you started.

    0 讨论(0)
  • 2021-02-19 02:20

    I had the same problem with select and includes. For eager loading of associated models I used native Rails scope 'preload' http://apidock.com/rails/ActiveRecord/QueryMethods/preload It provides eager load without skipping of 'select' at scopes chain.

    I found it here https://github.com/rails/rails/pull/2303#issuecomment-3889821

    Hope this tip will be helpful for someone as it was helpful for me.

    0 讨论(0)
  • 2021-02-19 02:20

    Allright so here's what I came up with...

    .joins("LEFT JOIN companies companies2 ON companies2.id = projects.company_id LEFT JOIN project_types project_types2 ON project_types2.id = projects.project_type_id LEFT JOIN users users2 ON users2.id = projects.user_id") \
    .select("six, fields, I, want")
    

    Works, pain in the butt but it gets me just the data I need in one query. The only lousy part is I have to give everything a model2 alias since we're using meta_search, which seems to not be able to figure out that a table is already joined when you specify your own join conditions.

    0 讨论(0)
  • 2021-02-19 02:23

    I wanted that functionality myself,so please use it. Include this method in your class

    #ACCEPTS args in string format "ASSOCIATION_NAME:COLUMN_NAME-COLUMN_NAME"

    def self.includes_with_select(*m)
        association_arr = []
        m.each do |part|
          parts = part.split(':')
          association = parts[0].to_sym
          select_columns = parts[1].split('-')
          association_macro = (self.reflect_on_association(association).macro)
          association_arr << association.to_sym
          class_name = self.reflect_on_association(association).class_name 
          self.send(association_macro, association, -> {select *select_columns}, class_name: "#{class_name.to_sym}")
        end
        self.includes(*association_arr)
      end
    

    And you will be able to call like: Contract.includes_with_select('user:id-name-status', 'confirmation:confirmed-id'), and it will select those specified columns.

    0 讨论(0)
  • 2021-02-19 02:26

    I might be totally missing something here but select and include are not a part of ActiveRecord. The usual way to do what you're trying to do is like this:

    Project.find(:all, :select => "users.name", :include => [:user, :company], :joins => "LEFT JOIN users on projects.user_id = users.id")
    

    Take a look at the api documentation for more examples. Occasionally I've had to go manual and use find_by_sql:

    Project.find_by_sql("select users.name from projects left join users on projects.user_id = users.id")
    

    Hopefully this will point you in the right direction.

    0 讨论(0)
提交回复
热议问题