Afsanefda
Afsanefda

Reputation: 3339

Assign a value to an active record relation field

This is my first model :

class Sender < ApplicationRecord
    has_many :letters
end

and this is the Second one:

class Letter < ApplicationRecord
  belongs_to :sender
end

I find a letter like this in rails Consol :

@letter = Letter.where(id: 378)

the result is :

#<ActiveRecord::Relation [#<Letter id: 378, indicator: "95/2", classification: "aa", urgency: "aa", package_id: nil, registrar_id: 0, user_id: nil, subset_type: "official", created_at: "2016-11-10 06:02:14", updated_at: "2016-11-10 06:02:14", sender_id: nil>]>

as you can see the sender_id is nil. The thing I want is to set a value to the sender_id like this :

@letter.sender_id = 12

but I got this error:

NoMethodError: undefined method `sender_id=' for #<Letter::ActiveRecord_Relation:0x00000004cc96c0>
Did you mean?  send_later
    from /var/lib/gems/2.3.0/gems/activerecord-5.0.0.1/lib/active_record/relation/delegation.rb:123:in `method_missing'
    from /var/lib/gems/2.3.0/gems/activerecord-5.0.0.1/lib/active_record/relation/delegation.rb:93:in `method_missing'
    from (irb):19
    from /var/lib/gems/2.3.0/gems/railties-5.0.0.1/lib/rails/commands/console.rb:65:in `start'
    from /var/lib/gems/2.3.0/gems/railties-5.0.0.1/lib/rails/commands/console_helper.rb:9:in `start'
    from /var/lib/gems/2.3.0/gems/railties-5.0.0.1/lib/rails/commands/commands_tasks.rb:78:in `console'
    from /var/lib/gems/2.3.0/gems/railties-5.0.0.1/lib/rails/commands/commands_tasks.rb:49:in `run_command!'
    from /var/lib/gems/2.3.0/gems/railties-5.0.0.1/lib/rails/commands.rb:18:in `<top (required)>'
    from bin/rails:4:in `require'
    from bin/rails:4:in `<main>'

What's wrong?

Upvotes: 1

Views: 1220

Answers (2)

Andrey Deineko
Andrey Deineko

Reputation: 52367

Letter.where(id: 378)

returns a collection of records matching the query condition. And of course, you do not have a method sender_id= for an ActiveRecord::Relation object.

What you want instead is a single record, which can be get by either

@letter = Letter.where(id: 378).first

or

@letter = Letter.find(id: 378)

Now, having a single record, you can update it's sender_id attribute:

@letter.update(sender_id: 12)

Upvotes: 1

Deepak Mahakale
Deepak Mahakale

Reputation: 23711

It should be

@letter = Letter.find_by_id(378)

# or

@letter = Letter.find(378)

because

@letter = Letter.where(id: 378)

will return you an array of records

Upvotes: 1

Related Questions