0
Rails.logger.info(params[:question])
=> {"title"=>"katt"}

@question_list.questions.create(params[:question])
=> ActiveModel::ForbiddenAttributesError (ActiveModel::ForbiddenAttributesError)    

 @question_list.questions.create("title"=>"katt")
# SUCCES!

I cannot understand why Rails not accepts the params when the exact same value written by hand works fine?

Update
controller:

def new_question
  @question_list.questions.create(params[:question])
  render nothing: true
end

private
  def set_question_list
    @question_list = QuestionList.find(params[:id])
  end

  def question_list_params
    params.require(:question_list).permit(questions_attributes: [:id, :question_list_id, :title, :position, :_destroy])
  end

view:

<%= form_for @question_list, url: new_question_question_list_path, remote: true do |f| %>
  <%= f.text_field :title %>
  <%= f.submit %>
<% end %>
Fellow Stranger
  • 32,129
  • 35
  • 168
  • 232
  • 1
    possible duplicate of [ActiveModel::ForbiddenAttributesError when creating new user](http://stackoverflow.com/questions/17335329/activemodelforbiddenattributeserror-when-creating-new-user) – Joe Kennedy May 27 '14 at 20:41
  • http://stackoverflow.com/a/17868685/1749024 – dasnixon May 27 '14 at 20:41
  • @JKen13579 I've read dozens of questions on SO already. The value inserted is the same, so I cannot see how strong parameters is the problem? – Fellow Stranger May 27 '14 at 20:44
  • Do you have a `question_params` method in your questions controller that contains the line `params.require(:question).permit(:title)`? – Joe Kennedy May 27 '14 at 20:47
  • `questions` are children of `question_list`. The code belongs to `QuestionListsController`. In the private method `question_list_params`: params.require(:question_list).permit(questions_attributes: [:id, :question_list_id, :title, :position, :_destroy]) – Fellow Stranger May 27 '14 at 20:50
  • Ah ok so you're not requiring/permitting `question`, you're instead permitting `questions_attributes`, which it seems like you aren't using. Can you post your full controller/form code for your `QuestionListsController`? – Joe Kennedy May 27 '14 at 20:54
  • Can you also add your `new_question` form? – Joe Kennedy May 27 '14 at 21:09
  • @JKen13579 OK updated. – Fellow Stranger May 27 '14 at 21:20
  • Is `QuestionList` a separate model? How are `QuestionList` and `Question` associated? I don't see any `fields_for` in your form, which is used for nesting. – Kirti Thorat May 27 '14 at 21:23
  • @KirtiThorat `QuestionList` one-to-many `Question`. http://stackoverflow.com/questions/23898486/controller-not-accepting-params-value-but-the-same-value-hard-coded-is-accepted?noredirect=1#comment36796949_23898486 – Fellow Stranger May 27 '14 at 21:24
  • Based on your controller and form, I'd suggest you try @zachar's solution. There is nothing in your code specifying that you're using "nested attributes", since you're sending a question to a question (within question_list) path, rather than sending a question list with a bunch of questions. If his solution doesn't work, I'll dig further for you. – Joe Kennedy May 27 '14 at 21:25
  • Thank you for your time @JKen13579, really, but I don't understand you guys. Nested attributes is a really accepted pattern. In what way is my strong parameters method (`question_list_params`) wrong? – Fellow Stranger May 27 '14 at 21:27
  • It's not that it's wrong, it's that you're not using it in your `new_question` method. Were a `question_list` object being passed with a list of questions (such as in a nested form) then you would be using your `question_list_params`, but you're passing a `question` object, as evidenced by the fact that you're using `params[:question]`. So, you need to let your controller know that you'd like to permit a question object. You do that by using a `question_params` method such as @zachar's. Hopefully that explanation helps... It's difficult to explain things in comments. :( – Joe Kennedy May 27 '14 at 21:35
  • @Numbers can you confirm you have defined in your question_list model accepts_nested_attributes_for :questions – Hare Kumar May 27 '14 at 21:51
  • @numbers Just for the reference, I will attach one of my code that creates questions and all it's associated child(answer options) in single query. I hope that might give you some idea. – Hare Kumar May 27 '14 at 21:56

3 Answers3

1

It's a Rails 4 new feature, called strong parameters. Check it: http://edgeapi.rubyonrails.org/classes/ActionController/StrongParameters.html

You need to enable attributes in controller. Try something like that:

class QuestionListsController < ApplicationController

def create

...

@question_list.questions.create(question_params)

end

...

private

def question_params

params.require(:question).permit(:title)

end

end

zachar
  • 1,085
  • 1
  • 11
  • 18
  • Thanks but my code has nested attributes and as you can see in the docs you provided (see the example with `Class Person`) there's another kind of syntax for nested attributes. – Fellow Stranger May 27 '14 at 21:01
1

With Rails 4, you would need to whitelist the attributes that you would like to be saved in database thats what Strong Parameters is all about. So, @question_list.questions.create(params[:question]) is not going to work in controller and would result in ActiveModel::ForbiddenAttributesError.

QuestionList has_many Questions, and you are trying to implement nested attributes, you should first start with fixing the form as there are NO nested attributes in there. Looking at the question_list_params, I can say that Question model has a field named title, so, your form should look something like:

<%= form_for @question_list, url: new_question_question_list_path, remote: true do |f| %>
  <%= f.fields_for :questions do |ff| %>
    <%= ff.text_field :title %>
  <% end %>
  <%= f.submit %>
<% end %> 

Next thing that you can do is update the new_question method as below:

def new_question
  @question_list.update(question_list_params)
  render nothing: true
end

@question_list.update(question_list_params) would take care of updating the question_list record PLUS the nested attributes of question.

Refer to Active Record Nested Attributes For One-To-Many Association for an example.

Kirti Thorat
  • 52,578
  • 9
  • 101
  • 108
0

Just for reference:

#Create question and it's options including correct answers.
def create

    if params[:question].present?      
      @question = Question.create(question_params)     
    else
      message("Failed", "400", "Parameter missing!", "Invalid parameters")
    end

end

private  

def question_params
      params.require(:question).permit(:word_id, :question_string, :level, :answers_attributes => [ :answer_string, :is_correct_choice])
end

I hope it will help you debug your code. And as @kirti has already suggested you can use the same format to do rest of the operation as well.

Hare Kumar
  • 699
  • 7
  • 23