Richlewis
Richlewis

Reputation: 15374

Accessing attributes from different associated models rails 3

I am looking to get a better understanding of Active Model/Record relationships and how to call attributes dependent upon where the attributes are located (models) and where I am calling them. So for example I can access the attribute dish_name from within the recipe controller like so

 def all_recipes
@recipes = Recipe.all
 end

In the view

<% @recipes.each do |r| %>
<%= r.dish_name %>
<% end %>

Now say i want to access a recipe attribute from within my controller called worldrecipes and i have just written a method that returns all recipes with the same country. a country has many recipes as a relation

So my method is

def self.top_countries
joins(:recipes).
  select('countries.*, count(*) AS recipes_count').
  group('countries.id').
  order('recipes_count DESC')
 end

My controller

@worldrecipes = Country.where(:name => params[:name])

and view

<% @worldrecipes.each do |r|  %>
<%= r.name %>
<% end %>

so accessing the country name attribute is easy as its in the country model and thats where my query results are being returned from (I think)...My question is how do i access the dish_name attribute from my recipe model to that links to the country name

Hope that makes sense, does anyone have a guide on how to work this out or some golden rules for this

Thank you

Upvotes: 3

Views: 3653

Answers (2)

Noz
Noz

Reputation: 6346

For starters you want to make sure you have the association setup in your models:

country.rb

class Country < ActiveRecord::Base  
  has_many :recipes
end

recipe.rb

class Recipe < ActiveRecord::Base  
  belongs_to :country
end

If you haven't already done so, add a foreign_key attribute to your recipe model by running the following migration:

rails g migration add_country_id_to_recipe country_id:integer

Now that your associations are in place you can easily query for a countries respective recipes. In your controller:

@worldrecipes = Country.where(:name => params[:name])

Then in your view:

<% @worldrecipes.each do |c|  %>
  <% c.recipes.each do |r| %>
   <%= r.dish_name %>
  <% end %>
<% end %>

In regards to 'golden rules' I highly recommend you check out Association Basics. This is the go-to place for an overview of what you can do with associations.

Upvotes: 3

Steve Robinson
Steve Robinson

Reputation: 3939

I think what you need is:

@country=Country.where(:name=>params[:name]).first
@[email protected]

And in the view:

<% @worldrecipes.each do |r|  %>
  <%= r.dish_name %>
<% end %>

This would print the dish names of the recipes of the country with name provided by params[:name]

EDIT: Ok Let me clear this up for you :)

Your model relationship is setup such that each country has many recipes. i.e a country has many recipes.

So you have,

has_many :recipes

in country.rb and

belongs_to :country

in recipe.rb

Now when you want to access all the recipes belonging to a country, what you do is, you call country_record.recipes (country_record being the object of the country record you need).

And when you call, Country.where(:name=>params[:name]) What you actually get is the active record object representing the COUNTRY itself and not the recipes of the country and that is why Italy was printed.

Hope this helped you.

Upvotes: 4

Related Questions