dannymcc
dannymcc

Reputation: 3824

Get parent attribute within new child form?

I have a simple Rails 3 application and I am trying to create a new record that belongs to it's owner. It's working by passing the id to a hidden field in the new form of the child record.

This works well and once the new child form submitted it correctly gets associated in the child/parent relationship.

What I am trying to do, is lookup values form the parent within the new child form. The problem is that the child relationship is not yet created. Is there anyway I can use a .where lookup in the view? Or, is there a better way of doing this?

At the moment I am passing the animal_id though to the new Claim form and it's inserted into a hidden field labelled animal_id.

What I am trying to do:

<%= @animal.where(:animal_id => params[:animal_id]).id %>

The above would ideally get the animal ID from the soon-to-be-associated animal. Is there any sort of before_filter or anything that could take the passed params from the URL and temporarily create the relationship just for the new form view and then permanently create the relationship once the form is submitted?

I've tried adding the following to my Claims controller and then called @animal.AnimalName in the view but I get NoMethodError:

before_filter :find_animal

protected
def find_animal
 if params[:animal_id]
   Animal.find(params[:animal_id])
 end
end

The URL of the new claim is correctly showing the animal ID so I'm not sure why it's not finding it:

http://localhost:3000/claims/new?animal_id=1

The model relations are as follows:

animal has_many claims
animal has_one exclusion

claim has_one animal

exclusion has_one animal

Update

I've corrected my relationships to as follows:

animal has_one exclusion
exclusions belong_to animal

Upvotes: 1

Views: 753

Answers (3)

ahnbizcad
ahnbizcad

Reputation: 10817

First, you should also update

claim has_one animal

to be

claim belongs_to: animal

, since you already have

animal has_many claims

From this, it seems like the parent is the Animal, and the Claim is the child, thus the child claim form is trying to somehow access the parent animal's id.


If I correctly understood your situation up to this point, why not just access the animal_id value you passed to the form? You've already passed that value to the new method in the claims_controller, right?

So when you press the submit button, and it passes all the values of the form, including the animal_id value, to the create method of the claims_controller,

claims_controller.rb

    def create
      @claim = claim.new(claim_params)
      if @claim.save
        redirect_to claim_path(@claim)
  else
        render 'new'
  end
    end

private

def claim_params
  params.require(:claim).permit(:foo, :bar. :animal_id)

end

Explanation: Once you click submit in your form, it will POST all of the data in the params hash called :claim. :foo :bar :animal_id would be three hypothetical names of three of your form fields, including your hidden animal_id.

We make a private method to take the accepted input strings form the form, and do .require and .permit to prevent from sql injection.

The claim_params method returns the hash of parameters required to pass into the Claim.new method so that you can create a new Claim object (aka row, aka record).

So claim.new(claim_params) creates a new claim from the form, including the animal_id, via the claims_params method's return value, which is was filtered from the form input.

The .new method creates a record, but does not actually save into the table. .save does.

Alternatively, instead of using .new and .save, you can use .create, which does both in succession in one shot.

Hopefully I understood your app, question, and needs well enough for this to be what you need.


I'm curious,

Also, can you clarify what is being excluded? That is, what the exclusion table looks like. Is the purpose to simply prevent some animals from being listed and "claim-able?"

What reason would there be for your application that it couldn't have the Animals model have a column named :excluded, and validate against duplications (the point being that you don't have one row of an animal as excluded and a second row of the same animal not excluded, resulting in a duplication)

Upvotes: 1

Piotr Mąsior
Piotr Mąsior

Reputation: 1580

with the relations update:

animal has_one exclusion
exclusion has_one animal 

due to documentation for has_one (http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_one)

Specifies a one-to-one association with another class. This method should only be used if the other class contains the foreign key.

and that somehow implicates that at least one side should have belongs_to definition on or has_many through something

Upvotes: 0

Piotr Mąsior
Piotr Mąsior

Reputation: 1580

Is there any sort of before_filter or anything that could take the passed params from the URL and temporarily create the relationship just for the new form view and then permanently create the relationship once the form is submitted?

I think the 'thing' you are looking for is build. Before filter will not solve that problem nicely.

Ruby on Rails. How do I use the Active Record .build method in a :belongs to relationship?

Build vs new in Rails 3

If it doesn't help can you post in here how did you implement models associations ?

Upvotes: 0

Related Questions