Update Rails column that expects array of strings using AJAX - ruby-on-rails

I'm trying to build a choose your own adventure game using Ruby on Rails and AJAX calls, where the games are user owned resources, and each game has a sentence column, expecting an array of strings.
game {
id: 16,
sentences: ['hello', 'world']
}
The above does not work when passed in as the data on an AJAX patch request (though I get 200 okay), neither does the hail-mary version of:
game {
id: 16,
sentences: 'hello'
}
The rails local server states that sentences are an unpermitted parameter.
started PATCH "/games/21" for ::1 at 2018-03-18 21:11:12 -0400
Processing by GamesController#update as */*
Parameters: {"game"=>{"id"=>"21", "sentences"=>["This is it: the end. You were wrong."]}, "id"=>"21"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."token" = $1 LIMIT $2 [["token", "8efb6bc10343a4415f6cbcb16d5184f2"], ["LIMIT", 1]]
Game Load (0.4ms) SELECT "games".* FROM "games" WHERE "games"."user_id" = $1 AND "games"."id" = $2 LIMIT $3 [["user_id", 2], ["id", 21], ["LIMIT", 1]]
Unpermitted parameters: :id, :sentences
(0.1ms) BEGIN
(0.1ms) COMMIT
[active_model_serializers] Rendered GameSerializer with ActiveModelSerializers::Adapter::Json (0.38ms)
Completed 200 OK in 5ms (Views: 0.7ms | ActiveRecord: 0.9ms)
This is maddening, because the parameter is specifically permitted in the controller.
def game_params
params.require(:game).permit(:hope, :wisdom, :user_id, :mnemonic, :sentences)
end
I can't get the sentences column to update using AJAX, though I'd added a method to the game model per this blog post's advice.
class Game < ApplicationRecord
belongs_to :user
def add_sentence(words)
sentences_will_change!
update_attributes sentences: sentences.push(words)
end
end
I can definitely update in the Rails console.
[3] pry(main)> game = Game.where(:id => 16).first
Game Load (0.3ms) SELECT "games".* FROM "games" WHERE
"games"."id" = $1 ORDER BY "games"."id" ASC LIMIT $2 [["id", 16],
["LIMIT", 1]]
=> #<Game:0x007ff420f750f0
id: 16,
hope: nil,
wisdom: nil,
created_at: Mon, 19 Mar 2018 00:33:57 UTC +00:00,
updated_at: Mon, 19 Mar 2018 00:33:57 UTC +00:00,
user_id: 1,
mnemonic: "ah",
sentences: ["hello", "world"]>
[8] pry(main)> game.update(sentences: ['hello', 'world', 'again'])
(0.2ms) BEGIN
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
SQL (0.4ms) UPDATE "games" SET "updated_at" = $1, "sentences" = $2 WHERE "games"."id" = $3 [["updated_at", "2018-03-19 00:37:36.428710"], ["sentences", "{hello,world,again}"], ["id", 16]]
(5.6ms) COMMIT
=> true
[10] pry(main)> game
=> #<Game:0x007ff420f750f0
id: 16,
hope: nil,
wisdom: nil,
created_at: Mon, 19 Mar 2018 00:33:57 UTC +00:00,
updated_at: Mon, 19 Mar 2018 00:37:36 UTC +00:00,
user_id: 1,
mnemonic: "ah",
sentences: ["hello", "world", "again"]>
[11] pry(main)>
Please help? I apologize for the foolishness of the question, I just can't figure out what is going wrong.

One issue appears to be that you don't actually have the :id in your permitted params, yet you are passing an id key in the provided examples.
For the sentences, try mapping the sentences key in your permitted params to an empty array:
def game_params
params.require(:game).permit(:hope, :wisdom, :user_id, :mnemonic, sentences: [])
end
More information in this stack overflow comment: https://stackoverflow.com/a/16555975/2909095

Related

Rails NoMethodError (undefined method `humanize' for nil:NilClass) in mail to:

I have such job in my Rails app:
class NewAnswerNotifyJob < ApplicationJob
queue_as :default
def perform(answer)
Services::NewAnswerNotify.new.send_notify(answer)
end
end
Services::NewAnswerNotify:
class Services::NewAnswerNotify
def send_notify(answer)
NewAnswerNotifyMailer.new.notify(answer)
end
end
NewAnswerNotifyMailer:
class NewAnswerNotifyMailer < ApplicationMailer
def notify(answer)
#answer = answer
#question = answer.question
#author = answer.question.author
mail to: #author.email
end
end
When I try in Rails console (I faced with this problem on a dev server, then have replayed this behavior in console) to run Services::NewAnswerNotify#send_notify with an answer I got such error:
2.6.0 :023 > answer = Answer.first
Answer Load (0.5ms) SELECT "answers".* FROM "answers" ORDER BY "answers"."best_solution" DESC LIMIT $1 [["LIMIT", 1]]
=> #<Answer id: 76, body: "answer body", question_id: 2, created_at: "2019-05-01 18:43:16", updated_at: "2019-05-28 15:38:16", author_id: 1, best_solution: true>
2.6.0 :024 > Services::NewAnswerNotify.new.send_notify(answer)
Question Load (0.6ms) SELECT "questions".* FROM "questions" WHERE "questions"."id" = $1 LIMIT $2 [["id", 2], ["LIMIT", 1]]
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Traceback (most recent call last):
3: from (irb):24
2: from app/services/new_answer_notify.rb:3:in `send_notify'
1: from app/mailers/new_answer_notify_mailer.rb:8:in `notify'
NoMethodError (undefined method `humanize' for nil:NilClass)
2.6.0 :025 >
So, the error occurs in mail to: #author.email line in NewAnswerNotifyMailer, but when but itself mailer works as planned:
2.6.0 :025 > answer = Answer.first
Answer Load (0.7ms) SELECT "answers".* FROM "answers" ORDER BY "answers"."best_solution" DESC LIMIT $1 [["LIMIT", 1]]
=> #<Answer id: 76, body: "for flexbox grid columns also means you can set th...", question_id: 2, created_at: "2019-05-01 18:43:16", updated_at: "2019-05-28 15:38:16", author_id: 1, best_solution: true>
2.6.0 :026 > NewAnswerNotifyMailer.notify(answer)
Question Load (0.5ms) SELECT "questions".* FROM "questions" WHERE "questions"."id" = $1 LIMIT $2 [["id", 2], ["LIMIT", 1]]
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
[i18n-debug] en.new_answer_notify_mailer.notify.subject => nil
Rendering new_answer_notify_mailer/notify.html.slim within layouts/mailer
Rendered new_answer_notify_mailer/notify.html.slim within layouts/mailer (4.7ms)
Rendering new_answer_notify_mailer/notify.text.slim within layouts/mailer
Rendered new_answer_notify_mailer/notify.text.slim within layouts/mailer (3.5ms)
NewAnswerNotifyMailer#notify: processed outbound mail in 100.5ms
=> #<Mail::Message:70164808395160, Multipart: true, Headers: <From: from#example.com>, <To: codcore#gmail.com>, <Subject: Notify>, <Mime-Version: 1.0>, <Content-Type: multipart/alternative; boundary="--==_mimepart_5d0cac2d80291_b85a3fd081039fd052340"; charset=UTF-8>>
I can't realize where problem is, why I get Nil at the Services::NewAnswerNotify.
Several suggestions:
You should use ActionMailer class methods directly instead of instantiating a new mailer with new. This is probably the source of the bug
Since your NewAnswerNotify is nested under Services, it would also make it less ambiguous to use the root namespace ::NewAnswerNotifyMailer (some people may disagree with me on this one, but I've had so many root namespace bugs in the past that I tend to systematically use the :: prefix now)
Beware of class loading that works differently for class Services::NewAnswerNotify and module Services class NewAnswerNotification (lots of existing questions on this topic)
module Services
class NewAnswerNotify
def send_notify(answer)
::NewAnswerNotifyMailer.notify(answer).deliver_now # instead of .new.notify
end
end
end
Also some side comments regarding the variables and the english
I would rather use
Services::NewAnswerNotification
NewAnswerNotificationMailer
def send_notification(answer) or def notify(answer)
And maybe one last piece of advice from experience after maintaining a code base in the long run: to be more explicit regarding who you are notifying of what def notify_question_author_of_new_answer because later you might have a notify_question_subscribers_of_new_answer or someone else who might need to be notified (it totally depends on your business model of course, feel free to ignore this remark)

Validation not passing for 'SyntaxError syntax error, unexpected tIDENTIFIER, expecting kEND):'

I am working on a checkout routine for a Rails webshop. Everything is working, but following a tutorial I placed a validation which throws a SyntaxError syntax error, unexpected tIDENTIFIER, expecting kEND): error.
When I uncomment it, everything works, but I still would like to implement a validation in this place.
The error is related to lines 17, 46 and 47 in the controller and 10 in the model.
The relative action in my controller is:
class CheckoutController < ApplicationController
def place_order
#page_title = "Checkout"
#order = Order.new(params[:order])
#order.customer_ip = request.remote_ip
populate_order ### LINE 17
...
end
private
def populate_order
#cart.cart_items.each do |cart_item|
order_item = OrderItem.new(:product_id => cart_item.product_id, :price => cart_item.price, :amount => cart_item.amount) ### LINE 46
#order.order_items << order_item ### LINE 47
end
end
end
The order_item model is:
class OrderItem < ActiveRecord::Base
attr_accessible :amount, :price, :product_id, :order_id
belongs_to :order
belongs_to :product
def validate
errors.add(:amount, "should be one or more") unless amount.nil? || amount > 0 ### LINE 10
errors.add(:price, "should be a positive number") unless price.nil? || price > 0.0
end
end
Not even stackoverflow lets me put in this line correctly
The error messages for line 10 and the pass with line 10 uncommented are as follows
Started POST "/checkout/place_order" for 127.0.0.1 at Tue Dec 11 08:03:05 +0100 2018
Processing by CheckoutController#place_order as HTML
Parameters: {"order"=>{"email"=>"test#example.tld", "ship_to_last_name"=>"Smith", "phone_number"=>"123451234134", "ship_to_first_name"=>"John", "ship_to_country"=>"United States of America", "ship_to_postal_code"=>"12345", "ship_to_address"=>"Somewhere Avenue", "ship_to_city"=>"Nowheretorn"}, "utf8"=>"✓", "authenticity_token"=>"xxxxx=", "commit"=>"Place Order"}
Cart Load (0.4ms) SELECT `carts`.* FROM `carts` WHERE `carts`.`id` = ? LIMIT 1 [["id", 3]]
CartItem Load (0.4ms) SELECT `cart_items`.* FROM `cart_items` WHERE `cart_items`.`cart_id` = 3
Completed 500 Internal Server Error in 5ms
SyntaxError (/Users/devaccount/Development/REPRO/webapp/app/models/order_item.rb:10: syntax error, unexpected tIDENTIFIER, expecting kEND):
app/controllers/checkout_controller.rb:46:in `populate_order'
app/controllers/checkout_controller.rb:45:in `populate_order'
app/controllers/checkout_controller.rb:17:in `place_order'
Started POST "/checkout/place_order" for 127.0.0.1 at Tue Dec 11 08:03:29 +0100 2018
Processing by CheckoutController#place_order as HTML
Parameters: {"order"=>{"email"=>"test#example.tld", "ship_to_last_name"=>"Smith", "phone_number"=>"123451234134", "ship_to_first_name"=>"John", "ship_to_country"=>"United States of America", "ship_to_postal_code"=>"12345", "ship_to_address"=>"Somewhere Avenue", "ship_to_city"=>"Nowheretorn"}, "utf8"=>"✓", "authenticity_token"=>"xxxxx=", "commit"=>"Place Order"}
Cart Load (0.2ms) SELECT `carts`.* FROM `carts` WHERE `carts`.`id` = ? LIMIT 1 [["id", 3]]
CartItem Load (0.4ms) SELECT `cart_items`.* FROM `cart_items` WHERE `cart_items`.`cart_id` = 3
SQL (0.1ms) BEGIN
SQL (1.4ms) INSERT INTO `orders` (`created_at`, `customer_ip`, `email`, `error_message`, `phone_number`, `ship_to_address`, `ship_to_city`, `ship_to_country`, `ship_to_first_name`, `ship_to_last_name`, `ship_to_postal_code`, `status`, `updated_at`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) [["created_at", Tue, 11 Dec 2018 07:03:29 UTC +00:00], ["customer_ip", "127.0.0.1"], ["email", "test#example.tld"], ["error_message", nil], ["phone_number", "123451234134"], ["ship_to_address", "Somewhere Avenue"], ["ship_to_city", "Nowheretorn"], ["ship_to_country", "United States of America"], ["ship_to_first_name", "John"], ["ship_to_last_name", "Smith"], ["ship_to_postal_code", "12345"], ["status", "open"], ["updated_at", Tue, 11 Dec 2018 07:03:29 UTC +00:00]]
SQL (1.1ms) INSERT INTO `order_items` (`amount`, `created_at`, `order_id`, `price`, `product_id`, `updated_at`) VALUES (?, ?, ?, ?, ?, ?) [["amount", 1], ["created_at", Tue, 11 Dec 2018 07:03:29 UTC +00:00], ["order_id", 7], ["price", 10], ["product_id", 13], ["updated_at", Tue, 11 Dec 2018 07:03:29 UTC +00:00]]
(0.5ms) COMMIT
SQL (0.1ms) BEGIN
(0.3ms) UPDATE `orders` SET `updated_at` = '2018-12-11 07:03:29', `status` = 'processed' WHERE `orders`.`id` = 7
(0.4ms) COMMIT
SQL (0.2ms) BEGIN
SQL (0.3ms) DELETE FROM `cart_items` WHERE `cart_items`.`id` = ? [["id", 11]]
(0.4ms) COMMIT
Redirected to http://localhost:3000/checkout/thank_you
Completed 302 Found in 138ms (ActiveRecord: 9.1ms)
I checked: amount has an integer value in the order_items table and is always greater than 0 in both cases.
I hope someone can point me into the right direction.

Rails creating a M:M relationship

I have a user and team models joined by a membership model.
One user can have many teams and each team can have many users etc.
class User < ApplicationRecord
has_many :memberships
has_many :teams, through: :memberships
End
class Team < ApplicationRecord
has_many :memberships
has_many :users, through: :memberships
End
class Membership < ApplicationRecord
belongs_to :user
belongs_to :team
end
I am looking for a way to simply create a memberships record however am missing something:
2.4.0 :026 > t = Team.last
Team Load (1.2ms) SELECT "teams".* FROM "teams" ORDER BY "teams"."id" DESC LIMIT $1 [["LIMIT", 1]]
=> #<Team id: 42129, name: "Reds", description: "A good team", created_at: "2017-05-18 05:05:09", updated_at: "2017-05-18 05:05:09">
2.4.0 :027 > User.first.memberships
User Load (1.7ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1 [["LIMIT", 1]]
Membership Load (1.1ms) SELECT "memberships".* FROM "memberships" WHERE "memberships"."user_id" = $1 LIMIT $2 [["user_id", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy []>
2.4.0 :028 > User.first.memberships << t
User Load (0.8ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1 [["LIMIT", 1]]
(0.4ms) BEGIN
(0.4ms) ROLLBACK
ActiveRecord::AssociationTypeMismatch: Membership(#23507760) expected, got #<Team id: 42129, name: "Reds", description: "A good team", created_at: "2017-05-18 05:05:09", updated_at: "2017-05-18 05:05:09"> which is an instance of Team(#33684520)
from (irb):28
2.4.0 :029 >
What am I missing here?
Update:
When I create a new memberships record and manually add the fk values I get this error when I try to save:
2.4.0 :037 > m
=> #<Membership id: nil, user_id: 1, team_id: 22641, created_at: nil, updated_at: nil>
2.4.0 :038 > m.save
(0.5ms) BEGIN
(0.4ms) ROLLBACK
NoMethodError: undefined method `class_name' for nil:NilClass
Did you mean? class_eval
from (irb):38
Update2
2.4.0 :022 > user = User.first
User Load (2.7ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1 [["LIMIT", 1]]
=> #<User id: 1, created_at: "2017-05-15 08:17:01", updated_at: "2017-05-19 02:54:30">
2.4.0 :023 > team = Team.first
Team Load (2.3ms) SELECT "teams".* FROM "teams" ORDER BY "teams"."id" ASC LIMIT $1 [["LIMIT", 1]]
=> #<Team id: 22641, name: "Reds", description: "This is a good team", created_at: "2017-05-18 01:41:00", updated_at: "2017-05-18 05:05:09">
2.4.0 :027 > Membership.delete_all
SQL (1.9ms) DELETE FROM "memberships"
=> 1
2.4.0 :029 > m=Membership.new(user: user, team: team)
=> #<Membership id: nil, user_id: 1, team_id: 22641, created_at: nil, updated_at: nil>
2.4.0 :031 > m.save
(1.0ms) BEGIN
SQL (2.3ms) INSERT INTO "memberships" ("user_id", "team_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["user_id", 1], ["team_id", 22641], ["created_at", "2017-05-22 03:37:22.803718"], ["updated_at", "2017-05-22 03:37:22.803718"]]
(2.1ms) COMMIT
=> true
2.4.0 :032 > Membership.delete_all
SQL (1.9ms) DELETE FROM "memberships"
=> 1
2.4.0 :033 > m=Membership.new
=> #<Membership id: nil, user_id: nil, team_id: nil, created_at: nil, updated_at: nil>
2.4.0 :034 > m.user_id=user.id
=> 1
2.4.0 :035 > m.team_id=team.id
=> 22641
2.4.0 :036 > m
=> #<Membership id: nil, user_id: 1, team_id: 22641, created_at: nil, updated_at: nil>
2.4.0 :037 > m.save
(0.5ms) BEGIN
User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
(0.8ms) ROLLBACK
NoMethodError: undefined method `class_name' for nil:NilClass
Did you mean? class_eval
from (irb):37
The first error message you're getting (before the Update) is because ActiveRecord is expecting an instance of Membership, and it's getting a Team. User.first.teams << t should work for that example.
As far as the error you shared in the Update, I didn't encounter that when I tried it, and it seemed to work fine with the relationships you gave.
2.2.3 :009 > user = User.first
User Load (0.2ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1
=> #<User id: 1>
2.2.3 :010 > team = Team.first
Team Load (0.2ms) SELECT "teams".* FROM "teams" ORDER BY "teams"."id" ASC LIMIT 1
=> #<Team id: 1>
2.2.3 :011 > membership = Membership.new(user: user, team: team)
=> #<Membership id: nil, user_id: 1, team_id: 1>
2.2.3 :012 > membership.save
(0.1ms) begin transaction
SQL (1.2ms) INSERT INTO "memberships" ("user_id", "team_id") VALUES (?, ?) [["user_id", 1], ["team_id", 1]]
(2.3ms) commit transaction
=> true
One thing to double check would be in how you're constructing the Membership record, and that there are no pluralization errors in the models. Passing in the actual User and Team instances to Membership.new or Membership.create should work.

Rspec case for rails 4 patch :update

I am using Devise in my app, and trying to write a spec for updating email ID. The UI works, but the spec is failing. I am reloading the user object as well, before testing against changed email ID.
One thing that I do observe is that there is UPDATE USERS statement being run on the database.
What is the correct way to write the spec?
RSpec spec:
it "should update email" do
#user = subject.current_user
patch :update, id: #user, user: {:email => "john.doe#example1.com"}
#user.reload
expect(#user.email).to eq("john.doe#example1.com")
end
RSpec Error Log:
1) Users::RegistrationsController logged in user should update email
Failure/Error: expect(#user.email).to eq("john.doe#example1.com")
expected: "john.doe#example1.com"
got: "john.doe#example.com"
(compared using ==)
test.log:
ActiveRecord::SchemaMigration Load (0.4ms) SELECT "schema_migrations".* FROM "schema_migrations"
(0.2ms) BEGIN
(0.4ms) SAVEPOINT active_record_1
User Exists (0.9ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = 'john.doe#example.com' LIMIT 1
SQL (4.1ms) INSERT INTO "users" ("created_at", "email", "encrypted_password", "first_name", "last_name", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id" [["created_at", Sat, 22 Jun 2013 13:12:28 UTC +00:00], ["email", "john.doe#example.com"], ["encrypted_password", "$2a$04$LIRWzphxstpCLTuZjicA..YMW.Ei2V/LlYWP32gfx39nBjhFg5tLe"], ["first_name", "John"], ["last_name", "Doe"], ["updated_at", Sat, 22 Jun 2013 13:12:28 UTC +00:00]]
(0.1ms) RELEASE SAVEPOINT active_record_1
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = 457 ORDER BY "users"."id" ASC LIMIT 1
Processing by Users::RegistrationsController#update as HTML
Parameters: {"id"=>"457", "user"=>{"email"=>"john.doe#example1.com"}}
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 457]]
User Exists (0.4ms) SELECT 1 AS one FROM "users" WHERE ("users"."email" = 'john.doe#example1.com' AND "users"."id" != 457) LIMIT 1
Rendered devise/registrations/edit.html.slim within layouts/application (0.2ms)
Completed 200 OK in 73ms (Views: 4.0ms | ActiveRecord: 1.0ms)
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 457]]
(0.2ms) ROLLBACK
Try
it "should update email" do
#user = subject.current_user
patch :update, id: #user, user: {:email => "john.doe#example1.com"}
#user.reload.email.should == "john.doe#example1.com"
end
Or alternatively
it "should update email" do
#user = subject.current_user
expect {
patch :update, id: #user, user: {:email => "john.doe#example1.com"}
#user.reload
}.to change(#user, :email).to("john.doe#example1.com")
end

Rails Engines - is it possible to add associations to the model in a container model like Forem does

This Question is more than a single question so breaking it up into more managable pieces: Rails Engines - simple possible engine to (1) add a model and (2) add the association in the containing class
I am testing out building a Rails engine and am curious whether I can add an association to a specific model in the hosting / container app.
The hosting app has a user model class (yes, this will never chnage) and my engine is called abc and I have a model in my engine called posts (so Abc::Post and the table is abc_posts). I'd like to add to the User class in the main app this association. As a drop dead simple try, I created in my engine:
#located in the engine at: abc/app/models/user.rb
class User < ActiveRecord::Base
has_many :abc_posts
end
the post file:
#located in the engine at: abc/app/models/abc/post.rb
module Abc
class Post < ActiveRecord::Base
attr_accessible :body, :header, :user_id
belongs_to :user
end
end
Via rails console, I was able to create records in the table (easy part) but the User class doesn't know about the association. Any ideas on how to get this done?
thx in advance
edit 1
I've tried using the decorators gem as used in forem (see comment below) and have this file:
#abc/app/decorators/lib/abc/user_class_decorator.rb
Object.const_get(User).class_eval do
has_many :abc_posts, :class_name => "Abc::Post", :foreign_key => "user_id"
end
I have included the decorators via:
lib/abc.rb
require "decorators"
but his doesn't seem to be working. Not sure if this is right strategy or whether syntax is even correct.
That should do the job - specify the class for the relationship:
class User < ActiveRecord::Base
has_many :posts, :class_name => "Abc::Post"
end
Hmmm, I created an example and it does work ...
class Parent < ActiveRecord::Base
has_many :children, :class_name => "Abc::Child"
end
The module with the class Child is in the model/abc.
module Abc
class Child < ActiveRecord::Base
belongs_to :parent
end
end
Here the journal
1.9.3-p194 :001 > Parent.create(:name => 'Mr Daddy')
(0.1ms) begin transaction
SQL (9.4ms) INSERT INTO "parents" ("created_at", "name", "updated_at") VALUES (?, ?, ?) [["created_at", Fri, 03 May 2013 10:49:54 UTC +00:00], ["name", "Mr Daddy"], ["updated_at", Fri, 03 May 2013 10:49:54 UTC +00:00]]
(1.9ms) commit transaction
=> #<Parent id: 1, name: "Mr Daddy", created_at: "2013-05-03 10:49:54", updated_at: "2013-05-03 10:49:54">
1.9.3-p194 :002 > Abc::Child.create(:name => 'Sammy boy', :parent => Parent.first )
Parent Load (0.3ms) SELECT "parents".* FROM "parents" ORDER BY "parents"."id" ASC LIMIT 1
(0.1ms) begin transaction
SQL (117.3ms) INSERT INTO "children" ("created_at", "name", "parent_id", "updated_at") VALUES (?, ?, ?, ?) [["created_at", Fri, 03 May 2013 10:49:58 UTC +00:00], ["name", "Sammy boy"], ["parent_id", 1], ["updated_at", Fri, 03 May 2013 10:49:58 UTC +00:00]]
(2.1ms) commit transaction
=> #<Abc::Child id: 1, name: "Sammy boy", parent_id: 1, created_at: "2013-05-03 10:49:58", updated_at: "2013-05-03 10:49:58">
1.9.3-p194 :003 > Abc::Child.create(:name => 'Milly girl', :parent => Parent.first )
Parent Load (0.3ms) SELECT "parents".* FROM "parents" ORDER BY "parents"."id" ASC LIMIT 1
(0.2ms) begin transaction
SQL (0.8ms) INSERT INTO "children" ("created_at", "name", "parent_id", "updated_at") VALUES (?, ?, ?, ?) [["created_at", Fri, 03 May 2013 10:50:15 UTC +00:00], ["name", "Milly girl"], ["parent_id", 1], ["updated_at", Fri, 03 May 2013 10:50:15 UTC +00:00]]
(2.7ms) commit transaction
=> #<Abc::Child id: 2, name: "Milly girl", parent_id: 1, created_at: "2013-05-03 10:50:15", updated_at: "2013-05-03 10:50:15">
1.9.3-p194 :004 > Parent.first.children.first
Parent Load (0.4ms) SELECT "parents".* FROM "parents" ORDER BY "parents"."id" ASC LIMIT 1
Abc::Child Load (0.3ms) SELECT "children".* FROM "children" WHERE "children"."parent_id" = ? ORDER BY "children"."id" ASC LIMIT 1 [["parent_id", 1]]
=> #<Abc::Child id: 1, name: "Sammy boy", parent_id: 1, created_at: "2013-05-03 10:49:58", updated_at: "2013-05-03 10:49:58">
1.9.3-p194 :005 > Parent.first.children.last
Parent Load (0.5ms) SELECT "parents".* FROM "parents" ORDER BY "parents"."id" ASC LIMIT 1
Abc::Child Load (0.4ms) SELECT "children".* FROM "children" WHERE "children"."parent_id" = ? ORDER BY "children"."id" DESC LIMIT 1 [["parent_id", 1]]
=> #<Abc::Child id: 2, name: "Milly girl", parent_id: 1, created_at: "2013-05-03 10:50:15", updated_at: "2013-05-03 10:50:15">
1.9.3-p194 :006 > Parent.first.children.count
Parent Load (0.3ms) SELECT "parents".* FROM "parents" ORDER BY "parents"."id" ASC LIMIT 1
(0.3ms) SELECT COUNT(*) FROM "children" WHERE "children"."parent_id" = ? [["parent_id", 1]]
=> 2

Resources