ActiveModel::ForbiddenAttributesError within Active Admin - ruby-on-rails-4

I have a model that is only ever created within active admin. I have the following controller setup:
def index
#events = Event.all
end
def new
#event = Event.new
end
def create
#event = Event.new(event_params)
end
private
def event_params
params.require(:event).permit(:venue, :trainer_id, :description, :training_request_id, :title, :date)
end
end
My event model is:
class Event < ActiveRecord::Base
has_one :trainer, inverse_of: :events
belongs_to :training_request, inverse_of: :event
delegate :module, to: :training_request
end
All the fields are there but I cant see why it is throwing this error.
Here is the output from the error:
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"H0sdhO3JsWBb8tYvFm52YvGsVvcnArigaVD+1r5HzL8=",
"event"=>{"training_request_id"=>"3",
"venue"=>"this is a venue",
"description"=>"this is a descripton",
"title"=>"event title",
"date(1i)"=>"2018",
"date(2i)"=>"3",
"date(3i)"=>"5",
"date(4i)"=>"05",
"date(5i)"=>"00",
"commit"=>"Create Event"}
Anyone got any ideas why this is happening?
Its worth mentioning that within rails console it saves fine.

I was missing
controller do
def permitted_params
params.permit event: [:venue, :trainer_id, :description, :training_request_id, :title, :date]
end
end
inside ActiveAdmin.register Event do

Related

In RoR, how do I avoid this "Unpermitted parameter" when submitting my form?

I’m using Rails 4.2.4. In my controller I have this
def update
#user = current_user
if #user.save_with_address(user_params)
…
end
private
def user_params
params.require(:user).permit(:first_name, :last_name, :dob, :address, :automatic_import)
end
and in my model (based on my “users” table in which I have a “users.address_id” column), I have this
class User < ActiveRecord::Base
belongs_to :address
attr_accessor :address
but when I submit my form to my “update” method (shown above) with the following data
Parameters: {"utf8"=>"✓", "authenticity_token"=>”tjLutbCuZUmLImSRnoRUCtcG8O0u070YixqjnMm5hmAZhn94fFte4jpWgB4hoOstiP9vJTj/c081EJ8NYnbMvg==", "user"=>{"first_name"=>"D.", "last_name"=>”LastName”, "dob(2i)"=>"", "dob(3i)"=>"", "dob(1i)"=>"", "address"=>{"city"=>"golden", "state"=>"3547", "country"=>"0"}, "automatic_import"=>"0"}, "commit"=>"Save", "id"=>"1"}
I get a “Unpermitted parameter: address” message when my “user_params” function is called and my address object isn’t saved as part of my user object. What do I need to structure differently to avoid this?
Since address is a hash you have to specify all its individual fields.
params.require(:user).permit(:first_name, :last_name, address: [:city, :state, :country])

Getting "Unpermitted parameter: address" even though I included field in my "permit" statement

I’m using Rails 4.2.3. I have this in my user_controller.rb …
def update
#user = current_user
if #user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to url_for(:controller => 'races', :action => 'index') and return
else
render 'edit'
end
end
private
def user_params
params.require(:user).permit(:first_name, :last_name, :dob, :address, :automatic_import)
end
and when my parameters get submitted to “update,”
Processing by UsersController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"bz24jRzK5qVWolW0oBoQbniiaQi96MeFFmzNjB4kCr0ifUYSsitvQIyod5AWDJd4KS3lrt3mzLiG8F9ef3aJkg==", "user"=>{"first_name"=>"Anthony", "last_name"=>"Alvarado", "dob(2i)"=>"1", "dob(3i)"=>"14", "dob(1i)"=>"1908", "address"=>{"city"=>"chicago"}, "automatic_import"=>"0"}, "state"=>"CT", "country"=>{"country"=>"233"}, "commit"=>"Save", "id"=>"13"}
Unpermitted parameter: address
Why am I getting this unpermitted parameter message when it is included in my “require” statement above? I even have this in my app/models/user.rb file …
class User < ActiveRecord::Base
…
belongs_to :address
There are 2 issues that are linked. (My assumption is that the user has one address, and not that the address has one user.) The model relationship should be:
class User < ActiveRecord::Base
…
has_one :address
accepts_nested_attributes_for :address
The address model:
class Address < ActiveRecord::Base
…
belongs_to :user
This should eliminate the unpermitted parameter error for address.

Rails 4 + ActiveAdmin passing params to another model and creating an object (with relations)

Total Rails novice here, just coming from PHP.
I'm running a Rails4+Active Admin setup with (device/cancan (disregarding those now).
Implementing strong_parameters. Please note, the code is totally broken. I've tried it in a bunch of ways and this is as close as I've gotten. Hopefully it gives a view into what I'm trying to do.
Been following a tutorial on implementing an API key setup, and trying to modify it to be able to generate an APIKey for a user in the admin.
I've added a column to AdminUser to generate an APIKey
It is correctly linked to
#app/admin/admin_users.rb
ActiveAdmin.register AdminUser do
index do
column :email
column :current_sign_in_at
column :last_sign_in_at
column :sign_in_count
default_actions
column('API', :sortable => :id) { |resource| link_to "(Re)Generate Key", new_admin_admin_user_api_key_path(resource.id) }
end
end
Which gives me a (correct) link to
/admin/admin_users/:admin_user_id/api_keys/new(.:format)
# app/admin/api_key.rb
ActiveAdmin.register APIKey do
belongs_to :admin_user
controller do
def create_for admin_user
key = APIKey.new
key.assign_params_from_controller(admin_user)
APIKey.create(:admin_user_id => params[:admin_user_id]);
end
def permitted_params
params.permit create_for [:admin_user_id]
end
end
end
#app/models/api_key.rb
class APIKey < ActiveRecord::Base
before_create :generate_access_token
belongs_to :admin_user, :foreign_key => "id", :inverse_of => :api_key
attr_accessible :admin_user_id
def assign_params_from_controller(params)
#params = params
end
private
def generate_access_token
begin
self.admin_user_id = params.admin_user_id
self.access_token = SecureRandom.hex
end while self.class.exists?(admin_user_id: admin_user_id, acces_token: access_token)
end
end
This code gives me:
NameError in Admin::APIKeysController#new
undefined local variable or method `params' for #<APIKey:0x000000078d6470>
def generate_access_token
begin
self.admin_user_id = params.admin_user_id
self.access_token = SecureRandom.hex
end while self.class.exists?(admin_user_id: admin_user_id, acces_token: access_token)
end
UPDATE, ANSWER:
Problem solved.
Ended up being on the right track. But was straying off because of type conversion errors.
My admin_user_id ended up being a 'string' in the database. Nice copy-paste job there.
Wrote a migration first
class AlterTableAPIKeys < ActiveRecord::Migration
def up
execute "DELETE FROM `api_keys` WHERE 1"
change_column :api_keys, :access_token, :string, { null: false }
change_column :api_keys, :admin_user_id, :integer, { null: false }
add_column :api_keys, :active, :boolean, {null: false, default: true }
remove_column :api_keys, :role
add_index :api_keys, ["admin_user_id"], name: "index_api_keys_on_admin_user_id", unique: false
add_index :api_keys, ["access_token"], name: "index_api_keys_on_access_token", unique: true
end
end
I didn't pass the access_token to the create.
I ended up with this.
# app/admin/api_key.rb
ActiveAdmin.register APIKey do
belongs_to :admin_user
controller do
def new
key = APIKey.create(:admin_user_id => params[:admin_user_id])
{:access_token => key.access_token}
redirect_to admin_admin_users_path, :notice => "API Key #{key.access_token} created! "
end
def permitted_params
params.permit api_key: [:admin_user_id]
end
end
end
# app/models/api_key.rb
class APIKey < ActiveRecord::Base
attr_accessible :access_token, :expires_at, :admin_user_id, :active, :application
before_create :generate_access_token
before_create :set_expiration
belongs_to :admin_user
def expired?
DateTime.now >= self.expires_at
end
private
def generate_access_token
begin
self.access_token = SecureRandom.hex
end while self.class.exists?(access_token: access_token)
end
def set_expiration
self.expires_at = DateTime.now+30
end
end
Obviously this does not account for access, might solve that with roles (i.e. uberadmin can regenerate other admins API, admins only their own).

has_many Nested Attributes in Rails 4 (save multiple objects with strong parameters)

I have a user who has_many services:
class User < ActiveRecord::Base
has_many :services
accepts_nested_attributes_for :services, :reject_if => lambda { |s| s[:name].blank? }, :allow_destroy => true
end
Here is my controller actions (devise)
def new
build_resource({})
5.times { resource.services.build }
...
end
def create
build_resource(sign_up_params)
resource.services.build(sign_up_params[:services_attributes])
...
end
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) do |u|
u.permit(:email, :password, :password_confirmation,
services_attributes: [:name])
end
end
When I submit my form here is the related params hash:
{...,
"services_attributes"=>{
"0"=>{"name"=>"Test"},
"1"=>{"name"=>""},
"2"=>{"name"=>""},
"3"=>{"name"=>""},
...}
Giving me the following error:
unknown attribute: 0
In that case I don't know how to save multiple objects with strong parameters. The idea I have is to do something like this:
in my create method:
resource.services.build(sign_up_params[:services_attributes][:id])
It saves objects but I am not feeling ok with this... Thanks for your explaination!
It should be only:
def create
build_resource(sign_up_params)
...
end

Carrierwave only upload image when update action when using Rails 4 and nested form

My model:
class Product < ActiveRecord::Base
has_many :product_images, dependent: :destroy
accepts_nested_attributes_for :product_images, :reject_if => lambda { |p| p['image'].blank? }, :allow_destroy => true
end
class ProductImage < ActiveRecord::Base
belongs_to :product
mount_uploader :image, ProductImageUploader
validates_presence_of :image
end
My controller:
def create
#product = Product.new(permitted_params.product)
if #product.save
redirect_to edit_admin_product_path(#product), notice: "success"
else
render :new
end
end
def update
#product = Product.find(params[:id])
if #product.update_attributes(permitted_params.product)
redirect_to edit_admin_product_path(#product), notice: "success"
else
render :edit
end
end
permitted_params:
class PermittedParams < Struct.new(:params)
def product
params.require(:product).permit(*product_attrs)
end
def product_attrs
[:name, :content, :stock, :list_price, :selling_price, :bonus, :is_added,
product_images_attributes: [:id, :image, :_destroy] ]
end
end
And parameters passed:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"eqweq1231sda+3T0131643guXybT75X6NqN1ng=", "product"=>{"name"=>"weqwe", "content"=>"qweq", "product_images_attributes"=>{"0"=>{"image"=>"1069218_513152615405563_1187314087_n.jpg", "_destroy"=>""}}, "stock"=>"", "list_price"=>"", "selling_price"=>"123", "bonus"=>""}, "commit"=>"submit"}
Obviously the image is pass to the params. but when create product it will rollback to alarm the image is empty(validate presence image in my ProductImage model).
If I delete the validation then create the product. I can successfully upload the images in update action. I have totally no idea what's the problem! Please help. Q_Q