I am working on a simple app that allows a user to write a post (parent_post), and another user to answer this post (child_post).
I am using the Ancestry gem to track the relationships between the posts.
Ancestry is a gem/plugin that allows the records of a model to be organised as a tree structure (or hierarchy). It exposes all the standard tree structure relations (parent, root, children, ancestors...).
The database schema.rb of the app:
create_table "posts", :force => true do |t|
t.text "title"
t.text "content"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "user_id"
t.string "ancestry"
end
create_table "users", :force => true do |t|
t.string "email", :default => "", :null => false
t.string "encrypted_password", :default => "", :null => false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "name"
end
The challenge:
I want to display informations about the author of the parent_post in the show view of a child_post .
Via the Ancestry gem you can call for "parent" and address all the columns inside of the posts table.
The posts table (see above) has a user_id column, so I can call
#post.parent.user_id
to show me the User ID, which works.
But I would like to show the username instead of the user_id.
Of course, user_id and username (name) are via the users table connected (see schema.rb above), but how can I address them here?
#post.parent.user_id.name is not working.
The models:
class User < ActiveRecord::Base
has_many :posts
end
class Post < ActiveRecord::Base
has_ancestry
belongs_to :user
end
I am still quite new to Rails and stuck here. Is there maybe a super easy solution I am not seeing?
Thank you so much for helping out!
How about #post.parent.user.name? I recommend making this a method on the Post model rather than your view or controller. Call it #post.original_poster_name or similar.
Related
Here are my two models
class Comment < ActiveRecord::Base
belongs_to :phone
end
class Phone < ActiveRecord::Base
has_many :comments, :dependent => :destroy
end
Here is the schema for the tables
ActiveRecord::Schema.define(version: 20131119231249) do
create_table "comments", force: true do |t|
t.string "username"
t.string "ipaddy"
t.text "pcomments"
t.string "company"
t.string "calltype"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "pnumber"
t.string "source"
end
create_table "phones", force: true do |t|
t.integer "pnumber"
t.text "mrcomment"
t.integer "ccount"
t.datetime "created_at"
t.datetime "updated_at"
end
end
Here is the raw SQL that works
SELECT phones.ccount ,
comments.*
FROM phones
INNER JOIN comments
ON phones.pnumber = comments.pnumber;
When I run the following in my controller
#phones = Phone.select("phones.ccount, comments.*").joins(:comments).where(:comments => {comments.pnumber => phones.pnumber})
I get the following error
undefined local variable or method `comments' for #<FrontPageController:0x00000003c56c70>
Any help on what the active record statement should like would be greatly appreciated
It seems like you're using the select() erroneously. Have you read the docs: http://apidock.com/rails/ActiveRecord/QueryMethods/select ?
from docs: "Second: Modifies the SELECT statement for the query so that only certain fields are retrieved:"
The query's syntax should more look like (using a standard example):
l = Location.where(["id = ?", id]).select("name, website, city").first.
I have the following app. A Movie has many reviews, a moviegoer has many reviews.
When I try to associate a review with a movie I get the following error
Review Load (0.1ms) SELECT "reviews".* FROM "reviews" WHERE "reviews"."movie_id" = 5
SQLite3::SQLException: no such column: reviews.movie_id: SELECT "reviews".* FROM "reviews" WHERE "reviews"."movie_id" = 5
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: reviews.movie_id: SELECT "reviews".* FROM "reviews" WHERE "reviews"."movie_id" = 5
after using a sql gui editor I found that the correct query should be
SELECT "reviews".* FROM "reviews" WHERE "movie_id" = 5
review.rb
class Review < ActiveRecord::Base
belongs_to :movie
belongs_to :moviegoer
attr_protected :moviegoer_id
end
movie.rb and moviegoer.rb have
has_many :reviews
in them.
schema.rb
ActiveRecord::Schema.define(:version => 20130222225620) do
create_table "moviegoers", :force => true do |t|
t.string "name"
t.string "provider"
t.string "uid"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "movies", :force => true do |t|
t.string "title"
t.string "rating"
t.text "description"
t.datetime "release_date"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "reviews", :force => true do |t|
t.integer "potatoes"
t.text "comments"
t.integer "moviegoers_id"
t.integer "movies_id"
end
end
What am I doing wrong? why is rails querying "reviews"."movie_id" instead of just "movie_id"?
You have the wrong column name in your migration. The rails convention is that foreign keys are to be singular. If they are not then you need to tell rails what the foreign key is with an options hash on the association.
Either rollback your migration, fix the column name (moviegoers_id is wrong as well) then migrate again, or tell rails the foreign key.
Class Review < ActiveRecord::Base
belongs_to :movie, :foreign_key => 'movies_id'
belongs_to :moviegoer, :foreign_key => 'moviegoers_id'
end
And the same has to happen on the has many side of both models.
I just want to make a little join table, eventually storing extra info on that join (which is why I'm not using HABTM). From the rails documentation of associations I've created the following models:
class Physician < ActiveRecord::Base
has_many :appointments
has_many :patients, :through => :appointments
end
class Patient < ActiveRecord::Base
has_many :appointments
has_many :physicians, :through => :appointments
end
class Appointment < ActiveRecord::Base
belongs_to :physicians
belongs_to :patients
end
my schema looks like this:
ActiveRecord::Schema.define(:version => 20130115211859) do
create_table "appointments", :force => true do |t|
t.datetime "date"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "patient_id"
t.integer "physician_id"
end
create_table "patients", :force => true do |t|
t.string "name"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "physicians", :force => true do |t|
t.string "name"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
end
When I'm in the console and I create a physician and patient instance:
#patient = Patient.create!
#physician = Physician.create!
And try to associate one to the other
#physician.patients << #patient
I get
NameError: uninitialized constant Physician::Patients
Questions about this example have been asked before but none have address my scenario. Any ideas?
Thanks,
Neil, rails newbie.
The belongs_to calls in your Appointment model should take a singular form, not a plural form:
class Appointment < ActiveRecord::Base
belongs_to :physician
belongs_to :patient
end
Hi I am new to rails ... I am trying to make a category and subcategory tree in rails...can you please guide me..
my schema is as follows:
create_table "categories", :force => true do |t|
t.string "name", :null => false
t.string "aka", :null => false
t.integer "parent"
end
you can find information here :
http://railscasts.com/episodes/162-tree-based-navigation
I'm a little stumped as to get the order of records I want with a find operation.
Let's say you had three models:
1. Websites
2. Links
3. Votes
A website has many links and a link has many votes. Each vote has a certain amount of points that a user can attribute to that vote. I'm trying to get a website index page where websites are listed in order of the sum of the points they've received for all the links for that website.
Here's a simplified version of the schema
create_table "votes", :force => true do |t|
t.integer "link_id"
t.integer "points"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id"
end
create_table "links", :force => true do |t|
t.string "name"
t.string "link"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id"
t.integer "votes_count", :default => 0
t.integer "website_id"
end
create_table "websites", :force => true do |t|
t.string "domain"
t.boolean "verified", :default => false
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
end
I'm trying to think about the right active record query to use here. Any help would be appreciated.
To think that I spent a day pulling my hair out when I came up with a solution just an hour after I posted this question.
In the website model I put that the website has_many :points, through => :links
Then the query:
array = Website.find(:all)
array.sort_by {|w| w.donations.sum('amount')}.reverse
This seems to work.