2

When you have a rails resource defined rails seems to automatically create a params entry of attributes for that resource. e.g. if my model Lesson has a subject attribute and I post subject=Maths it automatically creates the param[lesson] = { subject: 'Hello' }. The problem I am having is getting nested attributes to appear within this created lesson array.

I'm using mongoid as my backend and have an association on Lesson called activities. The code looks like this:

class Lesson
  include Mongoid::Document

  field :subject, type: String

  embeds_many :activities, class_name: 'LessonActivity' do
    def ordered
      @target.sort { |x, y| x.display_order <=> y.display_order }
    end

    def reorder!
      @target.each_with_index { |val, index| val.display_order = index }
    end
  end

  accepts_nested_attributes_for :activities

However I can't work out how I access this activities from within params.require(:lesson).permit :activities I can access it via params.permit(:activities) but that feels a bit messy

Baldrick
  • 23,882
  • 6
  • 74
  • 79
Kevin Dew
  • 220
  • 2
  • 9
  • This depends on what your form_for block of code looks like in your view. Could you share that so I can help? – Gjaldon Dec 18 '13 at 17:41
  • It's actually done via a JSON POST request. The posted data looks like this: {"date":"2013-09-04","date_position":1,"subject":"Maths","teaching_group":"6LP","activities":[{"title":"Starter","display_order":0,"content":null,"time":null},{"title":"Main","display_order":1,"content":null,"time":null},{"title":"Plenary","display_order":2,"content":null,"time":null}],"module":"","name":"","objectives":null} (note I simplified the class pasted in question for brevity) – Kevin Dew Dec 18 '13 at 18:06
  • does this help -http://stackoverflow.com/questions/18527708/strong-params-nested-attributes-and-mongoid-dont-seem-to-work-because-of-att ? – Jay Greasley Dec 20 '13 at 20:53

3 Answers3

2

I've done some digging and found out what's going on with this.

It all comes from a rails feature, the Param wrapper, details and api. Which configured for json will automatically pass the attributes of the model into a param of the model name (in this case Lesson).

The attributes of the model that will be populated based on how the model responds to the method attribute_names so this gives two routes to achieve the aims of the question.

1 - Instruct my controller to include activities as part of Lesson parameters, e.g. using this method:

class Api::LessonsController < Api::ApiController
  wrap_parameters Lesson, include: Lesson.attribute_names << :activities

2 - Update the attiribute_names method for the model to include :activities

I'm still left with a couple of things to resolve, namely the reason associations aren't part of attribute_names on Mongoid and if overriding it to include attribute names is a bad idea.

Kevin Dew
  • 220
  • 2
  • 9
0

Basing on the params you provided for your JSON POST request, you will need the following code to whitelist the params you need:

def activities_params
  params.require(:activities).permit(:title, :display_order, :content, :time)
end

The params forwarded by your JSON POST request did not have the :activities hash as a value to the :lesson key so whitelisting the params you need is simple like above.

Gjaldon
  • 5,534
  • 24
  • 32
  • Yup, I can access the activities param that way and merge it into lesson params (see bottom of my question). My question is how I can make it part of lessons key or why I can't. I'm not passing a lesson parameter so there's something in the Rails param mapping that's determining the attributes of my model and applying those to the parameters. Thanks. – Kevin Dew Dec 19 '13 at 01:02
  • For me to be able to help you with that, you'll need to also post the code for your form in the view. The params are populated based on the name attribute of each input field in the form. – Gjaldon Dec 20 '13 at 04:16
  • There isn't a form, I think I may have the answer now though will post it. – Kevin Dew Dec 22 '13 at 22:40
0

I think you may have answered you question here:

"how I can make it part of lessons key or why I can't. I'm not passing a lesson parameter "

If I read that correctly, you are not passing the lesson param, just a hash of Activities?

That would explain why you can access
params.permit(:activities) but not params.require(:lesson).permit :activities

  • I can access other things from the lesson hash without it, I've got why sussed now will post it. Thanks for answering though. – Kevin Dew Dec 22 '13 at 22:41