params.permit(
:type,
payload: [
user: [
:id, :email, :isAnonymous, :isAdmin, :firstName, :createdAt, :updatedAt, :phone, :inviteCode, :employeeId, :activated, :lastName,
:locked, :authVersion, :isCompanyAdmin, :isEditor, :isAnalyst, :isManager, :seenWebOnboarding, :language, :hidden, :deleted, :isSuperAdmin, :hasSignedInAsLearner,
:hasCreatedCourse, :hasInvitedAdmins, :isCompanyOwner, :sendActivationReminders, :timezone, :isUnsubscribedFromEngagementEmails, :authType, :activatedDate, :shouldShowGamificationOnboarding, :depositedPoints, :name,
:identifiers
],
course: [
:id, :customerId, :title, :courseKey, :public, :icon, :createdAt, :updatedAt, :courseImageUrl, :colour, :published, :type,
:requiresEnrolment, :isSample, :completionMessage, :completionButtonUrl, :completionButtonText, :isHidden, :learnersCount
],
parentGroup: [
:id, :customerId, :name, :createdAt, :updatedAt, :parentGroupId, :welcomePageConfigId, :selfSignupConfigId, :language, :deleted,
:ssoConfigId, :cookieConsentDisabled, :usersCount, :activatedUsersCount
],
completion: [
:overallAssessmentScore, :overallLessonScore, :scoresBreakdown, :courseStartDate, :courseCompletionDate,
:courseCompletionDurationInSeconds, :completionLanguage
]
],
:timestamp).to_h
end
This is the code that I'm having an issue with. When I try making a call to this endpoint, I run into this error.
syntax error, unexpected ')', expecting =>
:timestamp).to_h
^ excluded from capture: Not configured to send/capture in environment 'development'
I've noticed if I put the timestamp before the payload in the params.permit than this issue isn't there anymore. However, this is not how the request is going to formatted and I need to follow the structure of the request as it determines a hash later on in the code. Anyone know how to resolve this?
Even though you can do this in a method call, you can't have hash-style elements in a Ruby array. You need to have a formal hash inside of the array itself.
You need to split it out explicitly:
params.permit(
:type,
{
payload: [ ... ]
}
)
From further research, it seems that having a nested attributes must be permitted last. Makes sense as to why this only occurs when timestamp is behind payload.
I'm going to deal with this by just creating a new hash with the params later on with the correct structure.
source: https://smartlogic.io/blog/permitting-nested-arrays-using-strong-params-in-rails/
Related
I am maintaining a current Web Application (Ruby on Rails).
Our client wanted me to add this attributes contacts_attributes: [:id, :stock_holding_status] to the method below:
def meeting_log_params
params.require(:meeting_log).permit(
:id,
:stock_id,
:ir_meeting_id,
:start_at,
:end_at,
:kind,
:meeting_type,
:request_agent_company,
:request_agent_name,
:minute_taker,
:subject,
:content,
:memo,
:rating,
:country,
:city,
:attachment_1,
:remove_attachment_1,
:attachment_2,
:remove_attachment_2,
:attachment_3,
:remove_attachment_3,
interviewers_attributes: [
:id,
:meeting_log_id,
:resource_id,
:resource_type,
:_destroy
],
speakers_attributes: [
:id,
:meeting_log_id,
:resource_id,
:resource_type,
:_destroy
],
meeting_log_contacts_attributes: [
:stock_id,
:company_name,
:name,
],
ir_guests_attributes: [
:stock_id,
:department,
:title,
:last_name,
:first_name,
:department_en,
:title_en,
:last_name_en,
:first_name_en,
]
)
end
It is just that it returns me a 422 error (which means unprocessable entity) every time I used the added attribute on this method below.
Contact.update_stock_holding_statuses(meeting_log_params[:contacts_attributes])
I think it is because of the required(:meeting_log) that was before the permit method. Can you tell me how to exempt the required(:meeting_log) if I am going to use the added attribute on certain methods?
Like what I have in mind is like this:
params.require(:meeting_log ? :meeting_log : nil).permit( <all_attributes>)
I tried using ternary operators to exempt/disable the required part for me to use the added attribute which is contacts_attributes: [:id, :stock_holding_status] on a specific method and prevent the 422 from interfering. But it didn't work.
Any suggestions please.
Thank you!
How about simply
permitted_attributes = [:id,
:stock_id,
:ir_meeting_id,
:start_at,
:end_at,
:kind,
...
]
def meeting_log_params
meeting_log ? params.require(:meeting_log).permit(permitted_params) : params.permit(:permitted_params)
As far as I know, if the input parameters do not match require.permit, then you will get code 400 (not 422).
Code 422 is most likely related to the validation of the model when inside the update_stock_holding_statuses method.
I have in my model
class Account < ActiveRecord::Base
validates_length_of :amount, :in 1..255, :on => update, :if => Proc.new { |a| false if a.id == nil;a.amount.blank? }
validates_length_of :name, :in 1..255, :on => update, :if => Proc.new { |a| false if a.id == nil;a.name.blank? }, :unless => user_has_amount?
end
when I comment out the if condition, it works fine but with them validation fails which is confusing. I know that the validation should only run if the proc returns true or unless returns false
in my controller I have
#account.update_attributes({:name => "king", :amount => "1223"}
the save fails and when I check errors I get
#account.errors.details
{:name =>[{:error=>:too_short, :count=>1}], :amount =>[{:error=>:too_short, :count=>1}]}
Strong Params are not an issue because I have
def self.params
params.require(:account).permit!
end
I have no idea why it fails though the value are present and correct.
Try this the following:
class Account < ActiveRecord::Base
validates :amount, length: { in: 1..255 }, on: :update
validates :name, length: { in: 1..255 }, on: :update
end
Check your strong parameters. Your error tells you that something is wrong before you get to validation: :name =>[{:error=>:too_short, :count=>1}] This is saying that the minimum string count is 1 but that your string is not even that long. Here is the docs on that.
You can try: Account.find(1).update_attributes({:name => "king", :amount => "1223"} to see if #account is not being set properly.
You can also customize the language on your errors to help further:
validates_length_of : name, within: 1..255, too_long: 'pick a shorter name', too_short: 'pick a longer name'
The issue that was happening was for one reason. The code was inheriting from a class that had:
slef.reload
in one of the function that were being called during validations.
so every time we try to update the update failed because once that validation was hit it reloaded the original values from database and ignored new values which if old values are empty is just a head scratcher.
Thanks everyone for the help
I've been tinkering with the Rails 5.0 permit function for quite some time now, but I just can't get it right and really need some help:
I have this white listing function. And when executed I get the following response:
Unpermitted parameter: studio_users_attributes
I have this white listing function
def studio_params
params.require(:studio).permit(:name, :name_long, :address, :address2,
:zip, :city, :country, :phone,
:entity_id, { studio_users_attributes: [] } )
end
The params method returns me following:
{"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"VZTPSpsmNJxcqc[...]",
"studio"=>{"studio_users_attributes"=>{"0"=>{"viewing_rights"=>"Nur eigene",
"id"=>"4"}, "1"=>{"viewing_rights"=>"Alle", "id"=>"5"}}},
"commit"=>"Studio aktualisieren", "controller"=>"studios",
"action"=>"update", "id"=>"2"
}
Some help would be highly appreciated.
Philipp
In the controller you use studio_users_params.
But you send studio_users_attributes.
After some more experimenting I managed to solve it.
For the nested parameters I had to explicitly add the keys to the nested-hash:
def studio_params
params.require(:studio).permit(:name, :name_long, :address, :address2, :zip,
:city, :country, :phone, :entity_id,
studio_users_attributes: [:id, :viewing_rights] )
Leaving the hash empty (studio_users_attributes: []), would still result in
"Unpermitted parameter: studio_users_attributes "
While creating new Student Im getting error "no implicit conversion of Symbol into Integer"
In Students Controller,
def student_params
params.require(:student).permit(:name, :lastname, :subjects_attributes [:id, :name :_destroy, :mark_attributes [ :id, :value ]] )
end
What causes this problem ?
The problem is here:
:subjects_attributes [:id, :name :_destroy, :mark_attributes [ :id, :value ]] )
You should have a colon(:) after subject_attributes, not before it.
You can do either :subject_attributes => [:id, :name, :_destroy...] or subject_attributes: [:id, :name, :_destroy...]
The syntax without => is used with Ruby 2.0+, and is preferred one.
Bilal is correct. Also, you'll have to change :mark_attributes to mark_attributes:.
Why?
:subjects_attributes is a symbol. But subjects_attributes: [ ] is a hash where the key is :subjects_attributes (a symbol, as it turns out) and the value is [ ].
So, strong parameters knows how to process the hash defined by subjects_attributes: [ ] just fine.
But a symbol followed by an array, like :subjects_attributes [ ]? Well, that makes for all kinds of unhappiness accompanied by falling on the floor, kicking, and screaming.
As Bilal also points out, you can get back to a place of happiness by doing :subjects_attributes => [ ], which also creates hash and makes the sun shine again.
And that, my friend, is the answer to the question "What causes this problem?"
I have a collection of model objects that I am trying to return JSON for. E.G
#regions.to_json(:only => [:id, :name ])
that works fine.
If I try to use :
#regions.to_json(:only => [:friendly_id, :name ])
then nothing is returned for the friendly_id. The model does have:
has_friendly_id :name, :use_slug => true
So I am wondering what I am missing - or if I am not allowed to use
friendly_id's in to_json?
Try using
#regions.to_json(:only => [:id, :cached_slug])