Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use with namespaced models. #179

Closed
gpinkham opened this issue Nov 6, 2015 · 39 comments
Closed

How to use with namespaced models. #179

gpinkham opened this issue Nov 6, 2015 · 39 comments
Milestone

Comments

@gpinkham
Copy link

gpinkham commented Nov 6, 2015

I have a user model that lives in Platform::User.. I ran the generator with administrate::dashboard Platform::User and this created a user_dashboard.rb and a users_controller.rb.. when I try to go to the users page in admin it fails saying

uninitialized constant Admin::Platform

it points to this line in the controller:

class Admin::Platform::UsersController < Admin::ApplicationController

I tried to remove the Platform:: from the controller and dashboard file but that just produced a similar error but this time saying User was an uninitiatized constant.

thanks!
Gary

@tomgatzgates
Copy link

I'm looking for something similar.

I want to create a set of name spaced models that extend my application models so I can add in Admin specific methods and not pollute my application models.

@gpinkham
Copy link
Author

gpinkham commented Nov 6, 2015

I did some digging into the code.. the Resource Resolver uses the controller_path to create the class name.. for my Platform::User it was admin_users which in turn becomes User.. making it platform_users doesn't help as that becomes admin/platform_users and in turn PlatformUser not Platform::User..

@gpinkham
Copy link
Author

gpinkham commented Nov 6, 2015

feels like it's going to be quite a change to make this work. . every where I make a small change it leads down a path to some magic somewhere else in the gem. make a different change and some other magic fails. there's far too many assumptions that the classes do not have a namespace.. I will continue and see if I can get it working..

@tomgatzgates
Copy link

I'm at a point where I've modified the resource resolver for the namespaced class. I.e. models/admin/user.rb which inherits from models/user.rb

Currently working on getting the has_many and has_one collection tables working.
For example: User has many Orders
My error is undefined methodorder_path'. I need to it be looking foradmin_order_path`

I'l let you know if I get anywhere.

I'm struggling with lib/administrate/fields/has_many.rb resources method. I'm unsure where/what data is and where it comers from. If I knew that, I could change it to return Admin::Order.

@gpinkham
Copy link
Author

gpinkham commented Nov 9, 2015

BTW I had the named spaced model working though not happy with the implementation at the moment.. feels quite hackish.. (i have committed it to my fork last Friday).. Haven't tried any has many yet.. but will today.. I'm going to end up needing to handle namspaced models with nested forms.. so I'm sure I'll tackle a few things.. hoping this works.. tired of fighting with activeadmin.. :-)

@c-lliope
Copy link
Contributor

c-lliope commented Nov 9, 2015

@tomgatzgates I'd love to see your modified resource_resolver.

I think the solution might involve changing up the DashboardManifest list to use strings instead of symbols, and support namespaces through those. For example,

  DASHBOARDS = [
    "users",
    "store/line_items",
    "store/orders",
    "store/products",
  ]

I believe that ResourceResolver will be able to correctly look up these models without major changes. I'm not sure how the router would respond to it.

@c-lliope
Copy link
Contributor

c-lliope commented Nov 9, 2015

@gpinkham can you post a link to your fork? Interested in how you got it working!

@gpinkham
Copy link
Author

gpinkham commented Nov 9, 2015

funny thing.. just as your response came to my inbox I was experimenting with changing the dashboard manifest and the code in the routes to handle the names like as 'foo/bar'.. so my code that's in the repo does not have that. I just started to switch because I also use papertrail and its hard to determine in paper_trail_versions which part is the namespace and which part is simply camelcase to underscore.. never realized how much of a pain that ambiguity was.. here's my repo.. https://github.com/gpinkham/administrate

so I had forgotten to hit enter earlier today on this. updating now as I removed most of the code from Friday.. going with the 'namesapce/model' in the dashboard manifest and changing the code that administrate put into the routes.rb worked for me (plus a change I made on friday to a path lookup.. need to find that). I think I will redo this on a fresh fork and update the routes generator as well.. then submit a pull request (need to add tests too!)

@c-lliope
Copy link
Contributor

@gpinkham that sounds great, thanks! looking forward to seeing your solution.

@jshow
Copy link

jshow commented Nov 26, 2015

great to hear that I'm not the only (present) person needing namespaced support - @gpinkham how is your branch looking ?

thanks.

@gpinkham
Copy link
Author

@jshow sorry.. I have been off on other work. One of the guys on my team has been trying to get our activeadmin code ported over to administrate.. I'll admit neither of us are happy with some of the "hacks" we had to do to get things to work.. the namespace thing was easy compared to dealing with an engine.. Once I can wrap my head around everything I will see what I can do to contribute the work back..

@jshow
Copy link

jshow commented Nov 30, 2015

thanks @gpinkham - I've decided that Administrate is too raw at this juncture - I'll be starting with activeadmin until it evolves. cheers

@tanaylakhani
Copy link

I am trying to achieve the same. I am using pow have an api endpoint set as (following http://apionrails.icalialabs.com/book/frontmatter):

namespace :api, defaults: { format: :json },
                              constraints: { subdomain: 'api' }, path: '/'  do
    scope module: :v1, constraints: ApiConstraints.new(version: 1, default: true) do
        resources :users, :only => [:index,:show, :create, :update, :destroy]
        devise_for :users,  :controller => {:users => 'users'}
    end
end

I can navigate to /admin/users/1/edit and it displays the form correctly, but when I hit save it gives the error "No route matches [POST] "/admin/users/1"

Any suggestions?

@c-lliope
Copy link
Contributor

c-lliope commented Dec 1, 2015

@tanaylakhani I think you're seeing something different than the rest of this thread... Would you mind creating a new issue for it?

Thanks!

@c-lliope c-lliope added this to the v0.1.3 milestone Dec 8, 2015
@erickreutz
Copy link

Is this still on track for v0.1.3?

@c-lliope
Copy link
Contributor

@erickreutz, most of the features for v0.1.3 got pushed back to v0.1.4 - we've changed up v0.1.3 to be mostly generator improvements.

We've started tracking development progress with GitHub's milestones - you can see this one is in v0.1.4.

@trostli
Copy link

trostli commented Jan 18, 2016

I'm also interested in seeing a workaround for using namespace models, specifically for use with acts_as_taggable_on gem.

Did you end up making it work @gpinkham ?

@blahutka
Copy link

blahutka commented Feb 3, 2016

+1

@micapam
Copy link

micapam commented Feb 12, 2016

With a few tweaks to @gpinkham's fork I got namespaced models working well enough for my purposes:

https://github.com/micapam/administrate/commits/feature/namespaced-models

I haven't touched the generators, though. If I get time I will do so, but in the meantime (in my project) I did the following to get it working for me:

  • manually created the controller and dashboard in the appropriate subdirectories of app/controllers/admin and app/dashboards (i.e. subdirectories named after the namespace)
  • put a string rather than symbol into dashboard manifest
  • changed the routes config to recognise namespaces in DashboardManifest::DASHBOARDS, like so:
  namespace :admin do
    DashboardManifest::DASHBOARDS.each do |dashboard_resource|
      if dashboard_resource =~ /\//
        ns, res = dashboard_resource.split '/'
        namespace ns do 
          resources res
        end
      else
        resources dashboard_resource
      end
    end

    root controller: DashboardManifest::ROOT_DASHBOARD, action: :index
  end

@erickreutz
Copy link

Did this get pushed back from v0.1.4 to v0.1.5?

@jennykortina
Copy link

Hey Guys,

I'm trying to get administrate going and am having trouble with models that have Papertrail. Whenever I try to "edit" a model that has papertrail I get the error:

   uninitialized constant PaperTrail::VersionDashboard

I'm also using a gem "Payola" when I try to create/edit models with Payola attached I get the error:

 uninitialized constant Payola::SubscriptionDashboard

I believe these are both namespacing errors (from reading the thread above). Does anyone have any insight on how to fix these errors?

Thanks!

@murdoch
Copy link
Contributor

murdoch commented May 11, 2016

Are namespaced models still unsupported? I'm having the same issue with one that lives inside an engine (and is therefore namespaced).

@ACPK
Copy link

ACPK commented Jun 22, 2016

@Graysonwright - Is this still an issue, as I'm hitting the bug?

@ACPK
Copy link

ACPK commented Jun 22, 2016

@micapam - Thanks for the info! Any chance you could provide an example of "(2)put a string rather than symbol into dashboard manifest"?

@scarroll32
Copy link

scarroll32 commented Jun 23, 2016

@micapam @ACPK - Thanks for the fork, I could use an example on how to use it, but mostly I don't understand "put a string rather than symbol into dashboard manifest"

@ACPK
Copy link

ACPK commented Jun 23, 2016

@seanfcarroll - Sorry, I'm not following?

@scarroll32
Copy link

@ACPK did you work out how to use this fork?

@ACPK
Copy link

ACPK commented Jul 7, 2016

@seanfcarroll - Anything?

@scarroll32
Copy link

I gave up... Sorry am thinking of rolling my own admin panel

On 07 Jul 2016, at 17:27, Andrew Charles Potter Kelley notifications@github.com wrote:

@seanfcarroll - Anything?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

@waclock
Copy link

waclock commented Aug 1, 2016

Same problem here with papertrail.

@brlafreniere
Copy link

brlafreniere commented Aug 26, 2016

I'm running into this problem as well... name-spaced models aren't fully supported with this gem.

@carlosramireziii
Copy link
Collaborator

@nickcharlton We should try to address this one in an upcoming release

@danielricecodes
Copy link

danielricecodes commented Mar 2, 2017

@carlosramireziii - I figured out a place to start. It looks like if you don't rely on the generators and make a Dashboard and Controller with a namespace and place them in the directory structure Rails autoloader expects, you end up with 500 errors and helper methods would look like this: admin_blog/post_path instead of admin_blog_post_path.

If you look at lib/administrate/page/base.rb, it uses underscore. Underscore DOES NOT work with namespaces the way that method makes it sound. Rails documentation even says .underscore "Changes '::' to '/' to convert namespaces to **paths**." You should be using parameterize instead of underscore if resource_name is meant to be used to build Polymorphic URLs.

def resource_name
  @resource_name ||=
    dashboard.class.to_s.scan(/(.+)Dashboard/).first.first.parameterize(separator: '_')
end

My simple proof without trying a ton of use cases:

[4] pry(main)> 'Blog::Post'.underscore                  
=> "blog/post"
[5] pry(main)> 'Blog::Post'.parameterize(separator: '_')
=> "blog_post"

NOTE: The tricky part here is Rails framework version support. parameterize with kwargs is the preferred syntax. But in Rails 3, its .parameterize('_'). If you use that syntax with Rails 5, you get a deprecation warning.

I also had to override the default _sidebar partial. Again, parameterize to the rescue.

<ul class="sidebar__list">
  <% Administrate::Namespace.new(namespace).resources.each do |resource| %>
    <li>
      <%= link_to(
        display_resource_name(resource),
        [namespace, resource.to_s.parameterize(separator: '_')],
        class: "sidebar__link sidebar__link--#{nav_link_state(resource.to_s.parameterize(separator: '_'))}"
      ) %>
    </li>
  <% end %>
</ul>

In case it helps, here are my routes, dashboard, and controller for the Blog::Post model.

#routes

namespace :admin do
    resources :admin_users
    namespace :blog do
      resources :posts
    end

    root to: "admin_users#index"
 end

#app/admin/blog/posts_controller.rb

module Admin
  class Blog::PostsController < Admin::ApplicationController
  end
end

#app/dashboards/blog/posts_dashboard.rb

require "administrate/base_dashboard"

class Blog::PostDashboard < Administrate::BaseDashboard
  #normal stuff
end

danielricecodes pushed a commit to railsagency/administrate that referenced this issue Mar 2, 2017
…veRecord/Model classes. This allows one to reference ActiveModel’s route values (route_key, singular_route_key) when generating Polymorphic URLs.
@danielricecodes
Copy link

danielricecodes commented Mar 2, 2017

@carlosramireziii - made a ton of good progress on this one. I learned the real problem going on inside of Administrate's code is its reliance on ActiveSupport::Inflector helper methods. I will tidy up the branch I made on my company's fork and submit it back for review. The gist is that I allowed Administrate to expose ActiveModel::Name objects, which allows using route_key and singular_route_key in the polymorphic urls instead of resource_name. At the Core of each Administrate Page is an ActiveRecord class - so Administrate Page's need to make it easier to access them.

@klaseskilson
Copy link
Contributor

Isn't #688 pretty much what is needed to support namespaced models?

@carlosramireziii
Copy link
Collaborator

@danielricecodes Thanks for the detailed response! Would love to see your approach after you've cleaned up the branch.

To @klaseskilson's point, does your approach differ from #688? From skimming that PR, it seems to solve the problem by changing attribute names from symbols to strings and then using / to denote namespaced models. Without seeing it, yours sounds a bit simpler, but I'm not sure if both are tackling exactly the same problem or not.

WDYT?

@danielricecodes
Copy link

Sure thing. My approach is slightly diffferent than #688. I prefer to use ActiveModel::Name to get the correct display and route names of the ActiveRecord models that Pages wrap around. There may be a better way to specify a model for a given page than trying to infer it from routes also. I'm thinking about a more wholistic approach that can replace Administrates reliance on routes. I have the gem installed locally and have been hacking away. Give me a bit and I should have something. Then we can compare my solution with #688 and see which is preferred. Either way, a good discussion about code will ensue :)

danielricecodes pushed a commit to railsagency/administrate that referenced this issue Mar 2, 2017
…tiveModel::Naming to get at the correct resource names. It should still be possible to specify a resource here, instead of inferring it form the Dashboard class name.
@dmshvetsov
Copy link
Contributor

dmshvetsov commented Mar 3, 2017

The #688 PR supports both symbols and strings for attribute names. In addition the PR have changes for generators to support namespaced models.

I will be glad to hear feedback/ideas and to combine efforts to solve the issue.

@nickcharlton
Copy link
Member

nickcharlton commented Jul 14, 2017

I'm going to close this as #871 has been merged. Please open another issue if we've missed something!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.