I realize that this issue is likely in my app code, but I'm stumped as to where to look at this point.
I've successfully installed ActiveAdmin 1.0.0.pre4 on rails 4.2.1 (following instructions these instructions. I turned off authentication, since we already have devise set up with a custom admin system and I will configure ActiveAdmin to use it once we know it's working for us. I also configured the default_namespace to be activeadmin (not admin) since we already have custom administration tools under /admin.
/activeadmin successfully shows the Dashboard. So I added two models (Contact and Flag). Flags (/activeadmin/flags) works as expected - it shows all the records and Id, View, and Edit all link to the appropriate details view.
For Contacts, the list view works as expected (/activeadmin/contacts). It shows the records and the filters seem to work.
The problem is if I click on the Id, View or Edit links for any Contact they all show the same content: the details view of one of my Page records (which I had not yet even configured for ActiveAdmin). They show the SAME Page details - it has the title "Contact Us" (and the slug "contact-us"). Everything in the ActiveAdmin UI looks as it should: the URL is /activeadmin/contacts/39, the breadcrumb is right, even the panel title says "Contact Details". But regardless of which contact I choose, it always shows the Contact Us page.
I can short-circuit it by editing the contact.rb file for ActiveAdmin. However, I can only get it to show the "title" (from the Page Contact Us), not any other field. Everything else (whether it's from the Page model or the Contact model) throws an exception: undefined local variable or method `body' for #<ActiveAdmin::Views::Pages::Show:0x007fdfff3e7c40> Note that it's clearly looking for Pages, not Contacts. The request parameter is: {"controller"=>"activeadmin/contacts", "action"=>"show", "id"=>"39"}
Previously I had thought it had to do with the slug, although I have removed the friendly_id gem and commented out the code that references it (and errors imply it's no longer working). It made no difference.
Also:
- /activeadmin/contacts/ all show the Contact Us page details
- /activeadmin/contact-us or contact (with or without a /) gives a routing error (No route matches [GET] "/activeadmin/...")
I tried adding my Page model and then customizing page.rb with
ActiveAdmin.register Page, :as => "fancy_page"
(as I'd read in issue 959). But this did not change the behavior. Fancy Pages does indeed list all my pages, and Id, View, and Edit all link to the correct details page.
Rewriting my entire application to rename the Page model would be extremely difficult (the front-end website and associated custom CMS is the one part of our app that is fully working and live). I'm hoping there is a simpler fix, but I'm not really sure where to look.
Any suggestions?
Thanks!
julie
You need to customize the 'Form' configuration of contact's activeadmin resource by such configuration:
form do |f|
f.inputs 'Details' do
f.translated_inputs 'ignored title', switch_locale: false do |t|
t.input :name, :hint => 'Contact name'
t.input :email, :hint => 'Contact email'
end
end
actions
end
Note that you have to change name & email based on your model fields.
And to do more customization on the view (show action), you can do it by:
show do |contact|
attributes_table do
row :id
row :name
row :email
end
end
Related
I'm using ActiveAdmin as a CMS. I want my users to be able to create some pages and then these pages should be added dynamically in the active admin menu under a parent page called "Help". However, I can't workout how to register newly created pages, since the register_page method only runs when the server is started.
Is there a way to dynamically build the path to newly created pages? Or is there a way to run register_page dynamically (perhaps in a proc?) without having to restart?
Later edit:
The problem is the fact that I don't have a route for the newly created page so I get an error saying that admin_page_title_path could not be found after I create the page. This is because I'm doing a register_page in an after_create:
ActiveAdmin.register Page do
after_create do |page|
ActiveAdmin.register_page page.title do
menu :parent => 'Help'
content :title => proc { I18n.t("active_admin.manual") } do
columns do
column do
panel "#{raw(page.title)}" do
render :partial => "admin/pages/content", :locals => {page: page}
end
end
end #columns
end
end
end
end
If I use Rails.application.reload_routes! then the route is built, BUT this also clears my menus and I basically get a list of ALL the pages in the place where the menu used to be.
All the methods for rebuilding the menu that I tried seemed a bit hack-ish. So I assume there should be a way to rebuild just that one route instead of meddling with resetting resources and re-adding menu items.
In an ActiveAdmin page, I would like to include a link to a list of related resources. For example, given that a
Site has_many Sections and,
Section belongs_to a Site (in my ActiveRecord models),
I would like my Site's show page to include a link to Sections within the site, which would go to the Section index page, with the Site filter preset.
Note that
I do not want to use ActiveAdmin's belongs_to function;
I don't want nested resources for a number of reasons (depth of nesting > 2, as well as usability concerns).
What I want is to generate a URL similar to the one ActiveAdmin generates if I first go to the Sections index page and then filter by Site.
The query parameter list generated by ActiveAdmin's filtering feature is pretty crazy; is there a helper method I could use to achieve this goal?
Thanks!
I use this syntax:
link_to "Section", admin_sections_path(q: { site_id_eq: site.id })
I worked out a reasonably satisfactory solution after poking around in meta_search for a bit. Syntax is a bit clunky, but it does the trick.
index do
...
column "Sections" do |site|
link_to "Sections (#{site.sections.count})", :controller => "sections", :action => "index", 'q[site_id_eq]' => "#{site.id}".html_safe
end
end
As jgshurts pointed out, the trick is identifying that q[site_id_eq] query parameter.
However, if you don't like the clunky syntax, you can also just use a path helper:
link_to "Sections (#{site.sections.count})", admin_sections_path('q[site_id_eq]' => site.id)
The UrlHelper#link_to documentation shows additional examples of this.
#auto_link(resource, content = display_name(resource)) ⇒ Object
Automatically links objects to their resource controllers. If the
resource has not been registered, a string representation of the
object is returned.
The default content in the link is returned from
ActiveAdmin::ViewHelpers::DisplayHelper#display_name
You can pass in the content to display
eg: auto_link(#post, "My Link")
ActiveAdmin.register Girl do
index do
selectable_column
column :name do |girl|
auto_link(girl, girl.name)
end
column :email
column :created_at
actions
end
Useful-link: http://www.rubydoc.info/github/gregbell/active_admin/ActiveAdmin/ViewHelpers/AutoLinkHelper
Note: This is tested with ActiveAdmin (v1.1.0 and 2.0.0.alpha)
Hope this works with other version as well. Please update this answer if you are sure it works with other versions you know.
Let's say before a user is allowed to view the creation page of a Model, they are required to accept some terms. The workflow would be like:
User clicks on "create MODEL" -> Brought to a terms page, must accept before moving on -> MODEL creation page
If a user copies the url to the creation page, they should be redirected to the terms page.
What's the best way of going about this? I was thinking of using the session variable somehow...but I can't think of a clever enough idea. Any suggestions?
You can have the following routes:
get 'terms' => 'MODEL#terms'
get 'new' => 'MODEL#terms'
post 'new' => 'MODEL#new'
The "create MODEL" should send a GET request for /terms. Accepting the terms should POST to /new. If the user pasted /new in the URL, he'll be directed to terms instead.
Alternatively (or additionally), you can have the /terms POST a variable, :terms_accepted => true to the MODEL creation page, and on that page, check if :terms_accepted == true. If not, redirect to the terms page.
You can add the acceptance of the terms to the model itself, then you don't need a construction with an extra page and redirect if someone enters in the wrong place. Instead the user can only submit the form for creation when he/she accepts the terms.
You can add the following to the model:
class Model < ActiveRecord::Base
validates :terms_of_service, :acceptance => true
end
And then make sure you have the checkbox for this in the new %{model} form.
Also see: http://guides.rubyonrails.org/active_record_validations_callbacks.html#acceptance and Accept terms of use rails
I am trying to create profile pages for my community site. I have followed video tutorials and read docs on github for both Devise gem and CanCan gem. I have installed and currently have a functioning authentication system thanks to these two gems and the tutorials at railscasts.
I am very new to ruby and rails so everything is still very literal. My first question relates to a line of code from CanCan wiki page
<!-- in users/_form.html.erb -->
<%= f.collection_select :role, User::ROLES, :to_s, :humanize %>
I do not see a users folder or this controller. Is this something I can generate - for example I ran
rails g devise User
Could I also run:
rails g controller Users
I have seen this question here but do not quite understand the answer. Will I get an error by generating the "Users" controller to handle the things I would like to do?
I generated the devise views, but don't see any controllers - I understand that these could be overwritten - although I dont quite understand how this would work. If I overwrite than would all default devise controller functionality still work plus overwritten controller?
If I can generate the "Users" controller, I assume I could just put a view template into that location for all of the profile view information. I apologize for the amount of questions and length of this post, but I think with a little help I could be off and running again. Thanks for any information provided.
Alright so I solved this! I will post my solution for anyone with a similar question who could potentially benefit.
One of my questions was:
Could I also run:
rails g controller Users
Yes this is what I did. I use nifty scaffold generators to generate the views so this command would actually look like the following
rails g nifty:scaffold user
It is important to note that I DID NOT pass any variables after user. Devise has already created Users table in the database. This would create a conflict. Rails thinks you would like to overwrite your original database - which you do not want to do.
Do this builds the correct structure for User CRUD. Next open your config/routes.rb file.
Using nifty generators add the resources :users to the top of this file - move this below the devise resource and prefix the path as described on this devise wiki page to resemble the code below.
devise_for :users, :path_prefix => 'd'
resources :users
This is very important to remove any conflicts with your User controller and the devise controllers url paths by adding the "/d/" prefix to all devise controllers.
As well as adding the following code to you users_controller update method:
if params[:user][:password].blank?
params[:user].delete(:password)
params[:user].delete(:password_confirmation)
end
Which ensures devise will validate correctly.
Now comes the fun - register a user if you have not done so already. You now have a profile page for that user located at:
localhost:3000/users/1
localhost:3000/users/2
localhost:3000/users/3
...ect
You can edit user show.html.erb page in the views folder to change what information will display on each users profile page.
As for my question about Roles:
<!-- in users/_form.html.erb -->
<%= f.collection_select :role, User::ROLES, :to_s, :humanize %>
You now have access to this in the user controllers created by nifty-scaffold generator, so you can add this code to your form if you were also following Ryan Bates methods to integrate CanCan roles as described here.
Hopefully this help some else.
I am trying to construct my first new action in rails, thanks to the help of people here I have now got the vast majority working, but due to my mis-understanding of exactly how things work the action is not performing the desired action.
I have a database called Items, which contains :id, :external_url and :click_count
My goal is to have a link which when clicked on, the user is directed to the external url and :click_count is incremented by 1.
As it stands, I have the following:
view
<%= link_to image_tag( item.picture.to_s + ".gif"), items_clickcountplusone_path(:id => item.id)%>
items_controller
def clickcountplusone
clickeditem = Item.find(params[:id])
redirect_to clickeditem.external_url if clickeditem.update_attribute(:click_count, clickeditem.click_count + 1)
end
routes.rb
get 'items/:id' => 'items#clickcountplusone', :as => :items_clickcountplusone
Using this code, the page itself loads with all the links visible.
However, when I click on a link I get directed to items/whateveridiclickedon NOT the external URL and furthermore the :click_count value does not increase from its initial value.
Am I doing this correctly? In particular is the routes line ok, it currently appears as though i am instructing it to be directed to a specific page on my site for the item, which was not my intention... Also, what is wrong with the if statement meaning the count doesn't increase?
Many thanks for your patience
The mapped route "items/:id" is already associated with the show action and have precedence.
Try associating it with another URL.
get 'items/:id/visit' => 'items#visit', :as => :items_visit