john samcock
john samcock

Reputation: 137

add attribute to .create in rails

Lets say im saving an array into my model. Is there any way to add an attribute to it?

I am running Property.create(property_params) to save the instances of the array into my model

Is there anyway to append an extra attribute to property_params that is not passed in the json? Lets say i want to pass a global variable currentuserid set in create method into .create and save it to the attribute in the model user_id along with property_params?

I tried using .merge on property_params but it didnt work. I guess i need to pass it into the array?

Is this possible?

def create
 currentuserid = 4
 property_items = PropertyItem.create(property_params)
end

private

  def property_params
    params.permit(property: [:houses, :id, :father, :mother, :height, :children, :pets]).require(:property)
  end

This is my json below:

"property":[
    {
         "houses":"1",
         "id":"5",
         "father":"Jerry",
         "mother":"Tanya",
         "height":281,
         "children":2,
         "pets":24
      },
      {
         "houses":"3",
         "id":"5",
         "father":"Rob",
         "mother":"Anne",
         "height":726,
         "children":1,
         "pets":55
      }
   ]
}

Upvotes: 1

Views: 338

Answers (2)

m. simon borg
m. simon borg

Reputation: 2575

It would help to know what exactly you're trying to do, how you're handling this in the model, and why you're trying to do it this way.

When you require(:property) the result is the data structure nested one level deeper than :property, which is an array of params hashes. This is why you can't merge, or call permit after require. Because arrays don't respond to those methods. And if PropertyItem is an ActiveRecord object, you'll have a very hard time passing an array to create and getting that to work.

hash = {
  "property" => [
    {
      "houses" => "1",
      "id" => "5",
      "father" => "Jerry",
      "mother" => "Tanya",
      "height" => 281,
      "children" => 2,
      "pets" => 24
    },
    {
      "houses" => "3",
      "id" => "5",
      "father" => "Rob",
      "mother" => "Anne",
      "height" => 726,
      "children" => 1,
      "pets" => 55
    }
  ]
}

params = ActionController::Parameters.new(hash)

# => <ActionController::Parameters {"property"=>[{"houses"=>"1", "id"=>"5", "father"=>"Jerry", "mother"=>"Tanya", "height"=>281, "children"=>2, "pets"=>24}, {"houses"=>"3", "id"=>"5", "father"=>"Rob", "mother"=>"Anne", "height"=>726, "children"=>1, "pets"=>55}]} permitted: false>

params.permit(property: [:houses, :id, :father, :mother, :height, :children, :pets]).require(:property)

# => [<ActionController::Parameters {"houses"=>"1", "id"=>"5", "father"=>"Jerry", "mother"=>"Tanya", "height"=>281, "children"=>2, "pets"=>24} permitted: true>, <ActionController::Parameters {"houses"=>"3", "id"=>"5", "father"=>"Rob", "mother"=>"Anne", "height"=>726, "children"=>1, "pets"=>55} permitted: true>]

Merging the currentuserid into the params first, and then calling only permit without require gets you what I think you're looking for.

params.merge(currentuserid: 1).permit(:currentuserid, property: [:houses, :id, :father, :mother, :height, :children, :pets])

# => <ActionController::Parameters {"currentuserid"=>1, "property"=>[<ActionController::Parameters {"houses"=>"1", "id"=>"5", "father"=>"Jerry", "mother"=>"Tanya", "height"=>281, "children"=>2, "pets"=>24} permitted: true>, <ActionController::Parameters {"houses"=>"3", "id"=>"5", "father"=>"Rob", "mother"=>"Anne", "height"=>726, "children"=>1, "pets"=>55} permitted: true>]} permitted: true>

But I think an important question is still what exactly are you trying to do, and why?

Upvotes: 0

Mayur Shah
Mayur Shah

Reputation: 3449

Found the answer here you can insert it into the params definition with a merge

private

  def property_params
    params.require(:property).permit(:some_attribute).merge(user_id: current_user.id)
  end

or

def create 
  @property_items = PropertyItem.create(property_params) 
  @property_items.currentuserid = 4 
  #... 
end

Upvotes: 2

Related Questions