In the admin area, how do i go about and show the base errors (errors not specific to a field?). Ideally i would like to do this for all models.
Thanks
I just found an easy way to get them.. but you still have to override the form:
ActiveAdmin.register Blah do
form do |f|
f.semantic_errors :blah
f.inputs do
f.input :one
f.input :two
end
f.buttons
end
end
Update
You can simplify it like this too:
form do |f|
f.semantic_errors :blah
f.inputs
f.buttons
end
end
Well I hope I don't get flamed for this, but I dug into the ActiveAdmin Code and found where the default form options are.
Monkey Patch:
module ActiveAdmin::Views::Pages
class Form < Base
private
def default_form_config
ActiveAdmin::PagePresenter.new do |f|
f.semantic_errors
f.inputs
f.actions
end
end
end
end
That will make all the forms by default show errors that were added to base.
Related
I'm following this guide for multi-checkbox in rails. I am using Rails 3 conventions, so I still have attr_accessible instead of strong parameters. Everything seems to work fine except I get this error:
undefined method `match' for []:Array
userprofile.rb model:
class Userprofile < ActiveRecord::Base
before_save do
self.expertise.gsub!(/[\[\]\"]/, "") if attribute_present?("interest")
end
attr_accessible :interest, :user_id, :country, :state_prov, :city
serialize :interest, Array
userprofiles_helper.rb:
module UserprofilesHelper
def checked(area)
#userprofile.interest.nil? ? false : #userprofile.interest.match(area)
end
end
_form.html.erb:
<h3>Area of Interest</h3>
<%= label_tag 'interest_physics', 'Physics' %>
<%= check_box_tag 'userprofile[interest][]', 'Physics', checked("Physics"), id: 'interest_physics' %>
<%= label_tag 'expertise_maths', 'Maths' %>
<%= check_box_tag 'userprofile[interest][]', 'Maths', checked("Maths"), id: 'interest_maths' %>
If I remove the checked helper method, then the checkbox value does not persist. I've been trying to fix the undefined method 'match' error. Or find an alternate way to keep the correct checkbox value checked when I edit the form.
Any suggestions would help, thank you!
Since Userprofile#interest is an array, it looks like you actually want to use include? in your helper instead of match. So in userprofiles_helper.rb:
def checked?(area)
#userprofile.interest.present? && #userprofile.interest.include?(area)
end
I'm trying to use declarative authorisation at the model level using the query rewriting feature to filter down html select options something like this:
Model:
class TreatmentClinic < ActiveRecord::Base
def self.filtered_by_user_context
with_permissions_to(:read)
end
end
View(the new action):
<%= form_for(#something) do |f| %>
<%= f.select :id, TreatmentClinic.filtered_by_user_context.collect {|t| [ t.name, t.id ] }, {:include_blank => 'Please select'} %>
<%= f.submit %>
<% end %>
authorization_roles.rb:
role :some_role do
has_permission_on :treatment_clinics do
to :read
if_attribute :id => '1'
end
end
I'm using sorcery and have it working nicely with declarative authorisation; declarative authorisation permissions are working fine at the controller and view levels, but the above select is throwing this error:
No matching rules found for [:read] for #<Authorization::AnonymousUser:0x007fd257c00090 #role_symbols=[:guest]> (roles [:guest], privileges [:read, :manage], context :treatment_clinics).
Any ideas?
Just incase it helps anyone in the future, I found the answer. In order for declarative authorisation security to work at the model level we need to add this to the application_controller.
before_filter :set_current_user
protected
def set_current_user
Authorization.current_user = current_user
end
I have a Product model, set up with 4 children using STI.
My active_admin form looks like this:
form do |f|
f.inputs do
f.input :type, collection: Product.select_options
f.input :title
etc.
end
f.buttons
end
Relevant code from parent model:
def self.select_options
descendants.map{ |c| c.to_s }.sort
end
Initializer:
if Rails.env.development?
%w[product ring necklace bracelet earring].each do |c|
require_dependency File.join("app","models","#{c}.rb")
end
end
It all works fine and when I'm in the console I can do Product.select_options and it prints them out.
Why won't active_admin pick them up? It simply gives me a blank drop down with a tick inside it.
Thanks
You missed as: :select
Replace
f.input :type, collection: Product.select_options
With
f.input :type, as: :select, collection: Product.select_options
I have tried to get this working, looked at multiple tutorials, questions on here tried different things for about a week now and I can't get the view to work correctly.
I have teams of users. A team has_many users and a user belongs_to a team (one team at a time). I know the association works because I got it working using the console (with some help there). I'm not sure how to get it working in the view. Below is the code, please let me know if more is needed.
What am I missing?
_join_team_button
<%= form_for(#user) do |f| %>
<%= f.submit "Join Team", class: "btn btn-large btn-primary" %>
<% end %>
Team Show Page
<%= render 'shared/join_team_button %>
Teams Controller
def show
#team = Team.find(params[:id])
#team_members = #team.users
#user = current_user.users.build if signed_in?
end
Users Controller
def show
#user = User.find(params[:id])
#teams = #user.team
end
I tried to put a complete demonstration of what you are looking for. Let me know if it fits for you.
#FILE: models/team.rb
class Team < AR::Base
has_many :users
end
#FILE: models/user.rb
class User < AR::Base
belongs_to :team
end
#FILE: config/routes.rb
#Here you are defining "users" as a nested resource of "teams"
resources :teams do
resources :users do
member do
put :join
end
end
end
#if you run "rake routes" it will show you the following line along with others
join_team_user PUT /teams/:team_id/users/:id/join(.:format) users#join
#FILE: controllers/team_controller.rb
def show
#team = Team.find(params[:id])
#team_members = #team.users
#user = current_user.users.build if signed_in?
end
#FILE: views/teams/show.html.erb
<% if(#user) %>
<%= form_for #user, :url => join_team_user_path(#team, #user) do |f| %>
<%= f.submit "Join Team", class: "btn btn-large btn-primary" %>
<% end %>
<% end %>
#You dont really need a form for this. You can simply use `link_to` like below
<%= link_to 'Join', join_team_user_path(#team, #user), method: :put %>
#FILE: controllers/users_controller.rb
def join
# params[:id] => is the user_id
#user = User.find(params[:id])
# params[:team_id] => is the team_id
#team = Team.find(params[:team_id])
# Now make the relationship between user and team here.
#user.update_attribute(:team, #team)
end
Update:Based on your comment
Q: Do I create a new user's resource and nest that or do I nest the already establishes user's resource?
Ans: Based on your requirements any resource can be defined both independently or nestedly. But yes you can control that which method will be available in which way. Like in your case, you can allow only join method when your user is nested under team resource.
resources :users, :only=>:join do
member do
put :join
end
end
resource :users
run rake routes with and without :only=>:join option and see differences in available routes.
Q: Will that affect other things?
Ans: If you strictly define your routes following above example, it should not affect other things. You should confirm all the available routes to your application by rake routes.
Q: Should I put my current routes.rb file up there?
Ans: Assuming your current routes.rb will be modified in the above way. Could I answer the question?
Q: Confused about the comments controller?
Ans: Im extreamely sorry. Yes it must be users_controller.rb as the rake routes command is showing. Result of copy and paste from my own example code :P
Q: what should I put there? the build method
Ans: In your case both the user and team is already exists in your database. All you need to do is just setup a relationship. So you can just use update_attribute option. Ive changed the join method. Please check. But yes if want to create new entries you might need build methods.
Sorry for the late reply :)
I figured it out. Still not perfect, but it gets the association working. The team, and the user were already created, I just needed to establish the association, so the build method would not have worked. Here's what I have:
View:
<%= form_for(#user) do |f| %>
<%= f.hidden_field :team_id, :value => #team.id %>
<%= f.submit "Join Team", class: "btn btn-large btn-primary" %>
<% end %>
Teams Controller:
def show
#team = Team.find(params[:id])
#team_members = #team.users
#user = User.find(params[:id]) if signed_in?
end
I have found a lot of posts about this Railscast but all the suggestions haven't helped me.
I have been able to render in the view a nested form field, but only one, not the 3 that I have called out in my controller. When I submit, I get the error: Can't mass-assign protected attributes: clue
Chapter.rb
class Chapter < ActiveRecord::Base
belongs_to :trail
has_many :clues, :dependent => :destroy
accepts_nested_attributes_for :clues
attr_accessible :asset, :assetkind, :description, :gate, :name, :trail, :trail_id, :cover
.
.
.
end
Clue.rb
class Clue < ActiveRecord::Base
attr_accessible :chapter_id, :theclue, :typeof, :chapter
.
.
.
belongs_to :chapter
end
In the railcast it says to use the equivalent of :clues, and this renders 3 fields. But in mine, it didn't render the fields. Instead, I use #chapter.clues and it renders only one.
My form when making a new chapter.
<h1>Add a New Chapter</h1>
<h3>Add To Trail : <%= #trail.title %></h3><br>
<%= form_for [#trail, #trail.chapters.build] do |f| %>
<h6>About the Chapter</h6>
<%= f.label :name, 'Chapter Name' %>
.
.
.
<h6>Progressing the Story</h6>
<%= f.fields_for #chapter.clues do |builder| %>
<p>
<%= builder.label :theclue, "Enter Clue" %>
<%= builder.text_area :theclue, :rows => 2 %>
</p>
<% end %>
.
.
.
<% end %>
My chapters_controller.rb new
class ChaptersController < ApplicationController
def new
#trail = Trail.find(params[:trail_id])
#chapter = Chapter.new
#title = "Chapter"
3.times { #chapter.clues.build }
logger.debug "CHAPTER!!!!!!!!!!!!new: am i in a trail? #{#trail.to_yaml}"
logger.debug "CHAPTER!!!!!!!!!!!!new: am i in a clue? #{#chapter.clues.to_yaml}"
end
My log shows me 3 clues, but the attributes are empty (no :id). Is this a sign of something wrong? So even though my log shows 3 clue objects, my view only shows one.
Thoughts? I have already, thanks to suggestions on stackoverflow, added to chapter.rb
attr_accessible :clues_attributes
and had no luck, same behavior and errors with and without that.
Thanks in advance for your time
I figured it out for myself. Not sure why exactly, I will speculate, someone is welcome to explain it better if I'm off.
The issue was here:
<%= form_for [#trail, #trail.chapters.build] do |f| %>
which I changed to:
<%= form_for #chapter do |f| %>
and then I had to change some things around in my chapters_controller to make the trails objects and capture the ids. But, after I made this change, my 3 clue fields started showing up in the view and my error about mass-assign went away.
I think the chapter I created before was empty and not really generated, only holding information, so trying to hold nested information with the clues form_for was another step of temporary data...Where as creating the object in my controller and then filling it with the form was more substantial....I know really technical...Like I said, I got it working, don't ask me how...but I'm beginning to understand how Rails thinks.
When I submit, I get the error: Can't mass-assign protected attributes: clue
This is telling you that the attribute is protected from mass assignment. Basically, the only way you would be able to set it is through a method in your code, not from user input. (Which get assigned, usually, through update_attributes on the model.)
What you need to do is add :clue to attr_accessible in models/chapter.rb.
You may want to add :clues as well - I think it should actually be giving you the error that :clues is protected. You may run into an issue with :clue_ids. Whatever it says is protected, just put in the attr_accessible method in that model and you should be able to update it from user input.