Accessing a Has_One Associations' Attributes

Accessing a has_one associations' attributes

undefined method `name' for nil:NilClass

This says that you are trying to call some method name() on an an instance of Nil. Within your code's context, that says that chore on this line is nil

<td><%= user.chore.name %></td>

Simply put, one of the User instances in @user has no associated Chore. One simple way to accomodate this in your view is by checking if user.chore exists.

<td><%= user.chore.nil? ?  "some default name" : user.chore.name %></td>

Rails 4 - has_one - Can't access attributes of related model

As pointed out by janfoeh, you should have the following code in your Site model:

belongs_to :country
belongs_to :category

That way, you can do Site.find(1).country to return a site's country or Country.find(1).sites to return all sites found in a certain country.

If you want to do the "has_one" route, your data model should look like:

Site:

  • id
  • name
  • description
  • url

Category:

  • id
  • name
  • site_id

Country:

  • id
  • name
  • site_id

You should also change the code for your Country and Category models to have:

belongs_to :site

Rails 4 access table attributes from has_one association

How about:

# app/models/user.rb
class User < ActiveRecord::Base
has_one :account

scope :with_account_info, -> { includes(:account) }
default_scope{with_account_info}
end

The final two lines could be merged into one if you prefer that, i.e.:

default_scope{ includes(:account) } 

HTH

Nested attributes with has one association in Ruby on Rails

Step by step guide to build this association.

Add reference to house in address migration file t.belongs_to :house, index: true.

class CreateAddressses < ActiveRecord::Migration[5.2]
def change
create_table :addressses do |t|
t.belongs_to :house, index: true
t.string :state
t.timestamps
end
end
end

Add @house.build_address to HousesController new method

def new
@house = House.new
@house.build_address
end

Accept address params,

def house_params
params.require(:house).permit(:name, address_attributes: [:state])
end

Other sections of your code are correct including models.
Follow this tutorial on railscasts

Form with nested attributes with a has_one association not working in Rails 3

In rails 3 you should use (notice the equal sign in <%=):

<%= f.fields_for [...]

instead of :

<% f.fields_for

same goes with form_for

Collecting a set of has_one associations in an array

Not sure that I fully understand your question but I'll answer it as best I can. offer.location returns a collection of location objects so you can iterate over these objects and call the near method on each of them:

offer.location.each do |location|
location.near
end

However, I don't think this will work with the near method because it acts as a class level scope. It is not designed to work on an individual record.

The Geocoder gem does provide other methods that you can use on individual records, for example distance_from. So you could do something like:

offer.location.each do |location|
location.distance_from([40.714,-100.234])
end

Checkout the Geocoder docs for other available method calls.

Rails: Using build with a has_one association in rails

The build method signature is different for has_one and has_many associations.

class User < ActiveRecord::Base
has_one :profile
has_many :messages
end

The build syntax for has_many association:

user.messages.build

The build syntax for has_one association:

user.build_profile  # this will work

user.profile.build # this will throw error

Read the has_one association documentation for more details.

What's the use of has_one :through here (example from Rails guide)

There are cases where you might not want to add a specific field to a table. In your example you really only need one table as you can just add account_number and credit_ranking to the suppliers table. But sometimes it's a good idea to store the data across several tables. Then you have to use the has_one (one-to-one) relationship.

In your example you could also just add the attribute supplier_id to account_histories and replace has_one :account_history, :through account with just has_one :account_history but that would be redundant and also complicate your code as you would need to make sure that you don't change one attribute and forget to update the other one.

UPDATE:

If you don't add the supplier_id attribute to account_histories then Rails won't be able to determine which row from that table belongs to which supplier. The only way to find that out is to look in the related accounts table. Without accounts you can't determine which account_history belongs to a supplier as the accounts_histories table doesn't have any foreign keys for the suppliers table.

To get the account_history for a supplier without the :through option you would have to do this:

Supplier.find(id).account.account_history

:through allows you to replace it with this:

Supplier.find(id).account_history

As you've written in your update you could add the credit_ranking attribute to accounts and have only two tables. That would be even more simple but you just might want not to store that attribute in the same table (because maybe you already have lots of other attributes and don't want to add even more of them).



Related Topics



Leave a reply



Submit