For one of my models in ActiveAdmin, it is changing the URLs to use the name instead of ID.
For example: http://localhost:3000/admin/product/PH instead of http://localhost:3000/admin/product/1
I don't understand why it's doing that since all of the other models are working correctly (using ID).
This model has no models/product.rb file.
# app/admin/product.rb
ActiveAdmin.register Product do
permit_params :name,
:amount,
:description
end
I checked the documentation and didn't see anything that looks like it would make this happen.
Also, all of the other SO posts I've seen related to name and URL seem to be trying to do the opposite - changing the default route to use name (instead of ID).
Late reply, but I just met the same problem.
It was due to slug. I just remove slug from my model and it worked.
Hope it could help someone.
Related
Im building a membership web application with Ruby on Rails. I set up my DB and relationships between tables, everything worked fine. I decided to use Active Admin to shortcut the creation of a dashboard as well as providing a good search feature.
The issue I'm currently having is in Active admin on my dropdown list and table the foreign keys are only showing Id numbers and reference addresses (sorry, I forgot what their actually called).
Pics of my issue:
How can go about fixing this and in which files.
I would greatly Appreciate any help.
Customize ActiveAdmin Index Filters > Change The String Representation
Above article explains the similar issue. you have to do something like this in admin page for membership.
filter :plan, collection: -> {
Plan.all.map { |plan| [plan.name, plan.id] }
}
I have used name attribute for plan as an example. you may have different attribute, use correct attribute to reflect the details.
Update
Based on #DevOps92 answer
Alternate way to achieve this is to set any the method :display_name, :full_name, :name, :title, :to_s in Plan model
Active Admin Doc
For association columns we make an educated guess on what to display by calling the following methods in the following order:
:display_name, :full_name, :name, :username, :login, :title, :email, :to_s
This can be customized in config/initializers/active_admin.rb.
I solved the issue by going to my models that was generated by rails when I created the table in my database via scaffold. App/models/plan.rd and used the method display_name. Within the display_name method I listed the column name from the plan table. so anyone facing a similar issue check your rails models.
My Solution
Good Day All!
Edited for better understanding.
First model is Inventory and in this model I have Product_Type, Product_Name and User_ID.
Second model I have Users which consist of First_Name, Last_Name and Pin_Number.
On my Inventories page I have a form for checking out said Product_Type and Product_Name, also a place for a user to put their Pin_Number in. On submit, it will check the Pin_Number they have typed in and validate it in the Users model and if the Pin_Number is correct it will create an entry with said Product_Type, Product_Name and User_ID (which is pulled from Pin_Number that was submitted.)
I am just trying to figure out how to validate that Pin_Number they submitted.
Thats why I thought I had to do some kind of validation and an if statement based on that validation. Not sure how to go about that.
I hope this clears up any confusion.
I am just trying to figure out how to validate that Pin_Number they submitted.
What constitutes a valid pin_number? Just that it allows you to successfully look up a User? What if a user enters another user's pin_number? Is that considered 'valid'? Something to think about...
It would be helpful if you would add to your question what your params look like upon form submission. But, we can do some guess work.
So, let's assume that params looks something like:
{..., "inventory"=>{"product_type"=>"foo", "product_name"=>"Bar"}, "pin_number"=>5, ...}
In your controller, you'll probably do something like:
if #user = User.find_by(pin_number: params[:pin_number])
#inventory = Inventory.new(inventory_params)
#inventory.user = #user
if #inventory.valid?
#inventory.save
# perhaps do some other stuff...
else
# handle the case where the `#inventory` is not valid
end
else
# handle the case where the `#user` was not found
end
This assumes you have something like:
private
def inventory_params
params.require(:inventory).permit(:product_type, :product_name)
end
In your Inventory model, you probably want to do something like (I apologize, I'm not on Rails 5 yet, so some of the syntax may be incorrect):
class Inventory < ActiveRecord::Base
validates :user_id,
:product_type,
:product_name,
presence: true
belongs_to :user
end
You probably also want to consider adding an index on User.pin_number if you're going to be doing a lot of finding by it.
Not sure if I got the question right, but sounds like a custom validator to me.
You can learn more about custom validators in the official Rails documentation under "Custom Validators"
Also, consider moving the class for the custom validator you'll build to a concern, which is a great way to make it reusable. You can find more information on this StackOverflow question and this nice tutorial.
Another question from rails newbie. I am using friendly_id gem with mysql in rails 3.x
This is a design problem (may be easy in rails). I am expecting advises from rails experts. I am building a library listing app. Where user can view library by "metro-area" or by "city" in it. For example:
I wish to have URLs like:
www.list.com/library/san-francisco-bay-area
or
www.list.com/library/san-francisco-bay-area/palo-alto/
In database I have tables:
library
-------
id, name, city_id, slug
name is slugged here and city_id is FK
city
----
city_id, name, metro_area_id, slug
name is slugged here and metro_area_id is FK
metro_area
----------
metro_area_id, name, state, slug
name is slugged here
So when a user points browser to www.list.com/library/san-francisco-bay-area/palo-alto
I wish to get list of libraries in san-francisco-bay-area/palo-alto. But my library table model is containing slug only for library's name. So how this URL can be parsed to find the city_id that can be used in library model and controller to get the list.
Please remember, I cannot rely only on the name of the city. I would have to find city_id of 'palo-alto' which is in metro 'san-francisco-bay-area'. Since slug for metro_area and city is in other tables, so what is the best way to design model and controller.
Show method of controller is:
def show
#user = Library.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #library }
end
end
and model is
class Library < ActiveRecord::Base
attr_accessible :name, :city_id, :slug
extend FriendlyId
friendly_id :name, use: :slugged
end
This will not work per my friendly URL requirement. So I would appreciate advice from experts :)
Maybe you have found your solution, I'm new to rails as well, so I'm just guessing this would work out.
Since you wanna display slugs from two different models. I'm assuming the way to display ids would be something like
www.list.com/libraries/:id/cities/:id/metro_areas/:id
Which can be done through editing the route file by adding Nested Resources
As for just displaying two ids like
www.list.com/library/:city_id/:metro_area_id
Rails guide refers it as Dynamic Segments
After that, it's just a matter of converting the ids to slugs.
I also found this in FriendlyId's documentation which is addressing to your case.
Hope it helps
I'm a bit of a nube, and I am trying to piggyback on bokmann's rails3_fullcalendar to create a calendar app in rails 3.2, but when I try to create an event in my app I get this error:
ActiveModel::MassAssignmentSecurity::Error in EventsController#create
Can't mass-assign protected attributes: title, description, starts_at(1i), starts_at(2i),
starts_at(3i), starts_at(4i), starts_at(5i), ends_at(1i), ends_at(2i), ends_at(3i), ends_at(4i),
ends_at(5i), all_day
{"utf8"=>"✓",
"authenticity_token"=>"bq3ZUXLm4lYbja9FUafbroFF2Zwt8iMw6GWfvoRuPLA=",
"event"=>{"title"=>"sddfsdf",
"description"=>"df",
"starts_at(1i)"=>"2012",
"starts_at(2i)"=>"6",
"commit"=>"Create Event"}
The solution looks like it should be this but passing the AUTH_TOKEN with the AJAX POSTs (which it is sending) but it is still not working.
Any ideas?
The answer to your specific question is below, but a better answer is to look at the new version of that demo. Since the demo you're looking at, I have recreated the demo showing how to do this in Rails 3.2 with the fullcalendar JavaScript and css as an asset gem:
https://github.com/bokmann/fullcalendar_assets
Sometime recently (Rails 3.2?) the defaults for protection against mass assignment were changed... you now need to specifically allow the attributes that you want to allow mass assignment.
http://guides.rubyonrails.org/security.html#mass-assignment
In the event model, add a line that looks like this:
attr_accessible :title, :description, :starts_at, :ends_at, :all_day
If you get this Exception, you should already be authenticated, so the Auth_token is not your problem.
Rails has since version 3.2.3 a default to protect against mass-assignments.
You need to explicitly allow them in the model. That is why older code from third parties will fail. Change the model to:
class Event
..
attr_accessible :title, :description, starts_at ...
end
But do not include things like user_id into the list of allowed attributes, this way you prevent somebody who is only allowed to change her own events to reconnect the event that it will then to belong to another user.
See also the Rails Guide:
Security Guide, Mass assignment
The fullcalendar app appears to be created before config.active_record.whitelist_attributes = true became a rails default.
In your Event model, do you have a line like
attr_accessible :title, :description etc.?
Just trying out Mongoid at the moment, I've run into an issue that's probably pretty simple but has me at a loss:
I have a really simple Article model:
class Article
include Mongoid::Document
field :title, :type => String
field :content, :type => String
key :title
referenced_in :subject
validates_presence_of :title
end
I added key :title after I had already created one test record. Newly created records work as expected, but the first Article (which originally had the normal mongoid object id) behaves strangely:
In rails views this first article still returns its object id instead of the new key. ie using link_to article.name, article returns:
Show
... when all the rest return the parameterized keys, like:
Show
If I click that link I get "Record not found". I tried loading and resaving this record in the console, and after that calling article.id on that record did return the parameterized key, but it still shows up the old way in the view and doesn't work.
So, a couple questions:
What's going on here?
How do you fix it?
This situation indicates to me that if you set a field on a mongoid model to be the key, you need to be really sure that it will never change. How do you handle something like using the title of an article as a slug, then, when those may occasionally need change?
Thanks!
Well, since _id is immutable, your only option is to reinsert this document with your new 'sluggish' id and delete the old one.
And yes, _id format and shard key (if you use sharding) are the two things you better have right from the beginning :-)
Everything else can be fixed relatively easily.