Double Nested Includes











up vote
0
down vote

favorite












I have a navigation structure stored in a database. There are two models Navigation and Navigation Items.



class Navigation < ApplicationRecord

has_many :navigation_items

scope :all_items, -> {
includes(navigation_items: [:translations, children: :translations])
.order('navigation_items.position asc')
.where(navigation_items: { parent_id: nil })
}

end




class NavigationItem < ApplicationRecord

has_many :children, class_name: "NavigationItem", foreign_key: "parent_id"
belongs_to :parent, class_name: "NavigationItem", foreign_key: 'parent_id', optional: true
belongs_to :navigation
end




I setup the navigations in the application controller like this



def set_navigation
@navigations = Navigation.all_items
@navigation =
@footer_navigation =
@header_navigation =

if (main = @navigations.detect { |n| n.handle == "main" })
@navigation = main.navigation_items
end
if (footer = @navigations.detect { |n| n.handle == "footer" })
@footer_navigation = footer.navigation_items
end
if (header = @navigations.detect { |n| n.handle == "header" })
@header_navigation = header.navigation_items
end
end




I then loop through each navigation_item in the layout with a nested loop for the children.



All is working well except one thing. The navigation items all have a position tied to them. The parent items display in the correct order however the children are not obeying the order. Is there a way to also scope the children navigation items to order by position?










share|improve this question






















  • Would a default_scope for NavigationItem work? How about adding an order when calling navigation_items? I believe that the order for the all_items scope only applies to the initial query for Navigation, not to the subsequent queries for the includes relations.
    – shanecav
    Nov 10 at 23:09










  • I'm wrong about the order only applying to the initial query, at least on Rails 5.2.1. Which version of ActiveRecord are you on?
    – shanecav
    Nov 10 at 23:16










  • Hey @shanecav, also on rails 5.2.1. It is applying to the first level of navigation items but it is the sub items that are having trouble. I have tried default_scope with no luck.
    – trowse
    Nov 11 at 22:09















up vote
0
down vote

favorite












I have a navigation structure stored in a database. There are two models Navigation and Navigation Items.



class Navigation < ApplicationRecord

has_many :navigation_items

scope :all_items, -> {
includes(navigation_items: [:translations, children: :translations])
.order('navigation_items.position asc')
.where(navigation_items: { parent_id: nil })
}

end




class NavigationItem < ApplicationRecord

has_many :children, class_name: "NavigationItem", foreign_key: "parent_id"
belongs_to :parent, class_name: "NavigationItem", foreign_key: 'parent_id', optional: true
belongs_to :navigation
end




I setup the navigations in the application controller like this



def set_navigation
@navigations = Navigation.all_items
@navigation =
@footer_navigation =
@header_navigation =

if (main = @navigations.detect { |n| n.handle == "main" })
@navigation = main.navigation_items
end
if (footer = @navigations.detect { |n| n.handle == "footer" })
@footer_navigation = footer.navigation_items
end
if (header = @navigations.detect { |n| n.handle == "header" })
@header_navigation = header.navigation_items
end
end




I then loop through each navigation_item in the layout with a nested loop for the children.



All is working well except one thing. The navigation items all have a position tied to them. The parent items display in the correct order however the children are not obeying the order. Is there a way to also scope the children navigation items to order by position?










share|improve this question






















  • Would a default_scope for NavigationItem work? How about adding an order when calling navigation_items? I believe that the order for the all_items scope only applies to the initial query for Navigation, not to the subsequent queries for the includes relations.
    – shanecav
    Nov 10 at 23:09










  • I'm wrong about the order only applying to the initial query, at least on Rails 5.2.1. Which version of ActiveRecord are you on?
    – shanecav
    Nov 10 at 23:16










  • Hey @shanecav, also on rails 5.2.1. It is applying to the first level of navigation items but it is the sub items that are having trouble. I have tried default_scope with no luck.
    – trowse
    Nov 11 at 22:09













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I have a navigation structure stored in a database. There are two models Navigation and Navigation Items.



class Navigation < ApplicationRecord

has_many :navigation_items

scope :all_items, -> {
includes(navigation_items: [:translations, children: :translations])
.order('navigation_items.position asc')
.where(navigation_items: { parent_id: nil })
}

end




class NavigationItem < ApplicationRecord

has_many :children, class_name: "NavigationItem", foreign_key: "parent_id"
belongs_to :parent, class_name: "NavigationItem", foreign_key: 'parent_id', optional: true
belongs_to :navigation
end




I setup the navigations in the application controller like this



def set_navigation
@navigations = Navigation.all_items
@navigation =
@footer_navigation =
@header_navigation =

if (main = @navigations.detect { |n| n.handle == "main" })
@navigation = main.navigation_items
end
if (footer = @navigations.detect { |n| n.handle == "footer" })
@footer_navigation = footer.navigation_items
end
if (header = @navigations.detect { |n| n.handle == "header" })
@header_navigation = header.navigation_items
end
end




I then loop through each navigation_item in the layout with a nested loop for the children.



All is working well except one thing. The navigation items all have a position tied to them. The parent items display in the correct order however the children are not obeying the order. Is there a way to also scope the children navigation items to order by position?










share|improve this question













I have a navigation structure stored in a database. There are two models Navigation and Navigation Items.



class Navigation < ApplicationRecord

has_many :navigation_items

scope :all_items, -> {
includes(navigation_items: [:translations, children: :translations])
.order('navigation_items.position asc')
.where(navigation_items: { parent_id: nil })
}

end




class NavigationItem < ApplicationRecord

has_many :children, class_name: "NavigationItem", foreign_key: "parent_id"
belongs_to :parent, class_name: "NavigationItem", foreign_key: 'parent_id', optional: true
belongs_to :navigation
end




I setup the navigations in the application controller like this



def set_navigation
@navigations = Navigation.all_items
@navigation =
@footer_navigation =
@header_navigation =

if (main = @navigations.detect { |n| n.handle == "main" })
@navigation = main.navigation_items
end
if (footer = @navigations.detect { |n| n.handle == "footer" })
@footer_navigation = footer.navigation_items
end
if (header = @navigations.detect { |n| n.handle == "header" })
@header_navigation = header.navigation_items
end
end




I then loop through each navigation_item in the layout with a nested loop for the children.



All is working well except one thing. The navigation items all have a position tied to them. The parent items display in the correct order however the children are not obeying the order. Is there a way to also scope the children navigation items to order by position?







ruby-on-rails navigation sql-order-by rails-activerecord model-associations






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 10 at 21:17









trowse

749




749












  • Would a default_scope for NavigationItem work? How about adding an order when calling navigation_items? I believe that the order for the all_items scope only applies to the initial query for Navigation, not to the subsequent queries for the includes relations.
    – shanecav
    Nov 10 at 23:09










  • I'm wrong about the order only applying to the initial query, at least on Rails 5.2.1. Which version of ActiveRecord are you on?
    – shanecav
    Nov 10 at 23:16










  • Hey @shanecav, also on rails 5.2.1. It is applying to the first level of navigation items but it is the sub items that are having trouble. I have tried default_scope with no luck.
    – trowse
    Nov 11 at 22:09


















  • Would a default_scope for NavigationItem work? How about adding an order when calling navigation_items? I believe that the order for the all_items scope only applies to the initial query for Navigation, not to the subsequent queries for the includes relations.
    – shanecav
    Nov 10 at 23:09










  • I'm wrong about the order only applying to the initial query, at least on Rails 5.2.1. Which version of ActiveRecord are you on?
    – shanecav
    Nov 10 at 23:16










  • Hey @shanecav, also on rails 5.2.1. It is applying to the first level of navigation items but it is the sub items that are having trouble. I have tried default_scope with no luck.
    – trowse
    Nov 11 at 22:09
















Would a default_scope for NavigationItem work? How about adding an order when calling navigation_items? I believe that the order for the all_items scope only applies to the initial query for Navigation, not to the subsequent queries for the includes relations.
– shanecav
Nov 10 at 23:09




Would a default_scope for NavigationItem work? How about adding an order when calling navigation_items? I believe that the order for the all_items scope only applies to the initial query for Navigation, not to the subsequent queries for the includes relations.
– shanecav
Nov 10 at 23:09












I'm wrong about the order only applying to the initial query, at least on Rails 5.2.1. Which version of ActiveRecord are you on?
– shanecav
Nov 10 at 23:16




I'm wrong about the order only applying to the initial query, at least on Rails 5.2.1. Which version of ActiveRecord are you on?
– shanecav
Nov 10 at 23:16












Hey @shanecav, also on rails 5.2.1. It is applying to the first level of navigation items but it is the sub items that are having trouble. I have tried default_scope with no luck.
– trowse
Nov 11 at 22:09




Hey @shanecav, also on rails 5.2.1. It is applying to the first level of navigation items but it is the sub items that are having trouble. I have tried default_scope with no luck.
– trowse
Nov 11 at 22:09












1 Answer
1






active

oldest

votes

















up vote
0
down vote













try this



you can use default_scope or association condition



class Navigation < ApplicationRecord
# has_many :navigation_items, -> { where(parent_id: nil).order(position: :asc) }
has_many :navigation_items, -> { where(parent_id: nil) }

scope :all_items, -> { includes(navigation_items: [children: :children]) }
end





class NavigationItem < ApplicationRecord

# has_many :children, -> { order position: :asc }, class_name: "NavigationItem", foreign_key: "parent_id"
has_many :children, class_name: "NavigationItem", foreign_key: "parent_id"
belongs_to :parent, class_name: "NavigationItem", foreign_key: 'parent_id', optional: true
belongs_to :navigation

default_scope -> { order position: :asc }
end





share|improve this answer





















  • Thanks @PGill. Unfortunately it is still ordering the children incorrectly. I think I need to change the default order somehow to be order by parent.position then position.
    – trowse
    Nov 18 at 1:48











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53243495%2fdouble-nested-includes%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
0
down vote













try this



you can use default_scope or association condition



class Navigation < ApplicationRecord
# has_many :navigation_items, -> { where(parent_id: nil).order(position: :asc) }
has_many :navigation_items, -> { where(parent_id: nil) }

scope :all_items, -> { includes(navigation_items: [children: :children]) }
end





class NavigationItem < ApplicationRecord

# has_many :children, -> { order position: :asc }, class_name: "NavigationItem", foreign_key: "parent_id"
has_many :children, class_name: "NavigationItem", foreign_key: "parent_id"
belongs_to :parent, class_name: "NavigationItem", foreign_key: 'parent_id', optional: true
belongs_to :navigation

default_scope -> { order position: :asc }
end





share|improve this answer





















  • Thanks @PGill. Unfortunately it is still ordering the children incorrectly. I think I need to change the default order somehow to be order by parent.position then position.
    – trowse
    Nov 18 at 1:48















up vote
0
down vote













try this



you can use default_scope or association condition



class Navigation < ApplicationRecord
# has_many :navigation_items, -> { where(parent_id: nil).order(position: :asc) }
has_many :navigation_items, -> { where(parent_id: nil) }

scope :all_items, -> { includes(navigation_items: [children: :children]) }
end





class NavigationItem < ApplicationRecord

# has_many :children, -> { order position: :asc }, class_name: "NavigationItem", foreign_key: "parent_id"
has_many :children, class_name: "NavigationItem", foreign_key: "parent_id"
belongs_to :parent, class_name: "NavigationItem", foreign_key: 'parent_id', optional: true
belongs_to :navigation

default_scope -> { order position: :asc }
end





share|improve this answer





















  • Thanks @PGill. Unfortunately it is still ordering the children incorrectly. I think I need to change the default order somehow to be order by parent.position then position.
    – trowse
    Nov 18 at 1:48













up vote
0
down vote










up vote
0
down vote









try this



you can use default_scope or association condition



class Navigation < ApplicationRecord
# has_many :navigation_items, -> { where(parent_id: nil).order(position: :asc) }
has_many :navigation_items, -> { where(parent_id: nil) }

scope :all_items, -> { includes(navigation_items: [children: :children]) }
end





class NavigationItem < ApplicationRecord

# has_many :children, -> { order position: :asc }, class_name: "NavigationItem", foreign_key: "parent_id"
has_many :children, class_name: "NavigationItem", foreign_key: "parent_id"
belongs_to :parent, class_name: "NavigationItem", foreign_key: 'parent_id', optional: true
belongs_to :navigation

default_scope -> { order position: :asc }
end





share|improve this answer












try this



you can use default_scope or association condition



class Navigation < ApplicationRecord
# has_many :navigation_items, -> { where(parent_id: nil).order(position: :asc) }
has_many :navigation_items, -> { where(parent_id: nil) }

scope :all_items, -> { includes(navigation_items: [children: :children]) }
end





class NavigationItem < ApplicationRecord

# has_many :children, -> { order position: :asc }, class_name: "NavigationItem", foreign_key: "parent_id"
has_many :children, class_name: "NavigationItem", foreign_key: "parent_id"
belongs_to :parent, class_name: "NavigationItem", foreign_key: 'parent_id', optional: true
belongs_to :navigation

default_scope -> { order position: :asc }
end






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 17 at 23:46









PGill

1,2321013




1,2321013












  • Thanks @PGill. Unfortunately it is still ordering the children incorrectly. I think I need to change the default order somehow to be order by parent.position then position.
    – trowse
    Nov 18 at 1:48


















  • Thanks @PGill. Unfortunately it is still ordering the children incorrectly. I think I need to change the default order somehow to be order by parent.position then position.
    – trowse
    Nov 18 at 1:48
















Thanks @PGill. Unfortunately it is still ordering the children incorrectly. I think I need to change the default order somehow to be order by parent.position then position.
– trowse
Nov 18 at 1:48




Thanks @PGill. Unfortunately it is still ordering the children incorrectly. I think I need to change the default order somehow to be order by parent.position then position.
– trowse
Nov 18 at 1:48


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53243495%2fdouble-nested-includes%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Guess what letter conforming each word

Port of Spain

Run scheduled task as local user group (not BUILTIN)