.last method working weirdly rails - ruby-on-rails

I have an Model named Page
class Page < ApplicationRecord
has_many :details, dependent: :destroy
end
and Detail
class Detail < ApplicationRecord
belongs_to :page
end
Everything was working fine, but now when I call
page.find(29).details.last(2), it gives
[#<Detail id: 379, followers: 1055869, follows: 42, media_count: 325, page_id: 29, created_at: "2017-03-15", updated_at: "2017-03-16 19:31:26">,
#<Detail id: 309, followers: 785870, follows: 0, media_count: 0, page_id: 29, created_at: "2017-03-10", updated_at: "2017-03-10 23:30:10">]
and if I try page.find(29).details.last
#<Detail id: 309, followers: 785870, follows: 0, media_count: 0, page_id: 29, created_at: "2017-03-10", updated_at: "2017-03-10 23:30:10">
why its showing record with id= 309 as latest instead of 'id=379'
To clarify I manually updated record with id=309 before this issue,
I tried to update id='379' but still its showing last record as id=309
(moreover I also changed created_at type to date from datetime a month ago as I needed it)
'm I missing something or its actually weird (its on live server I really need to fix it)
Regards

Related

Load related model in rails 7

I'm new in ruby rails and face some difficult to achieve something.
Now I have a product model:
class Product < ApplicationRecord
belongs_to :category
And category model:
class Category < ApplicationRecord
has_many :products
When I call the product like so: #products.inspect i wan to see the category belongs to the product. My output now looks like so:
<ActiveRecord::Relation [#<Product id: 1, name: "Adidas", description: "Adidas is a Dutch multinational corporation that i...", price: 100, created_at: "2022-08-23 10:02:11.110159000 +0000", updated_at: "2022-08-23 10:02:11.114384000 +0000", category_id: 1>, #<Product id: 2, name: "asd", description: "12easd", price: 12, created_at: "2022-08-24 09:35:38.839809000 +0000", updated_at: "2022-08-24 09:35:38.847999000 +0000", category_id: 1>]>
Getting the product.category working fine, but, I need also the name of the category attached to this output. I need this because the product is sent to a JavaScript function and I need to call the category name from there.
What I already try is the follow:
def index
#products = Product.includes(:category).all
end
Thanks in advance.
I found it!
#product.to_json(include: :category)
And now I get the related category model

rails check_box_tag to include existing values of from array of records

The following tag in a nested form
<%= check_box_tag "friend_ids[]", ff.id, #contentrestrictions.friends.include?(ff.id) %>
is handling the following array of records
>> #contentrestrictions
[
#<Contentrestriction id: 29, usercontent_id: nil, friend_id: nil, created_at: "2019-04-28 10:55:32", updated_at: "2019-04-28 10:55:32">,
#<Contentrestriction id: 30, usercontent_id: nil, friend_id: 2, created_at: "2019-04-28 10:55:32", updated_at: "2019-04-28 10:55:32">,
#<Contentrestriction id: 31, usercontent_id: nil, friend_id: 4, created_at: "2019-04-28 10:55:32", updated_at: "2019-04-28 10:55:32">]
Even though
class Contentrestriction < ApplicationRecord
belongs_to :friend, optional: true
#contentrestrictions. followed by any of friend_id, friend_ids both appended with or without [] all lead to NoMethodError: undefined method for Array.
how can this include function get a proper array to work with?
the issue is in this line:
#contentrestrictions.friends.include?(ff.id)
you are comparing a friend object with a friend id, you could use pluck to get the friend ids, or you could just compare the objects:
#contentrestrictions.friends.include?(ff)
this will make a query for the .friends and you could remove this query by pre-loading the friends association, e.g. eager_load(:friends) or includes(:friends)

Rails - how to automatically uniq joins method?

This question is based on this: Rails, why joins returns array with non-uniq values?
Let say I get non uniq array by .joins() method:
City.joins(:locations)
# => [#<City id: 5, name: "moscow", created_at: "2010-07-02 15:09:16", updated_at: "2010-07-02 15:09:16">, #<City id: 5, name: "moscow", created_at: "2010-07-02 15:09:16", updated_at: "2010-07-02 15:09:16">, #<City id: 5, name: "moscow", created_at: "2010-07-02 15:09:16", updated_at: "2010-07-02 15:09:16">, #<City id: 5, name: "moscow", created_at: "2010-07-02 15:09:16", updated_at: "2010-07-02 15:09:16">]
I can make records uniq by using
City.joins(:locations).group('cities.id') # or simpler
City.joins(:locations).uniq
# => [#<City id: 5, name: "moscow", created_at: "2010-07-02 15:09:16", updated_at: "2010-07-02 15:09:16">]
How can I make .joins() method returns uniq records by default?
You could try overriding the .joins method for the models you need, but I would suggest just writing a scope, e.g.
scope :unique_locations, -> { joins(:locations).uniq }
Then just call City.unique_locations. It's cleaner and more readable that way.
Generally overwriting methods should be done only when you're sure you won't need it 'the old way', and it makes sense. Plus, when you say City.joins(:locations) the reader expects default behaviour, and returning something else will cause chaos and confusion.
You can define has_many macro, with the stubby lambda as an argument:
has_many :locations, -> { joins(:locations).uniq }
Also you can define own AR relation method, it stil use a simple has_many macro.
has_many :locations do
def only_uniq
joins(:locations).uniq
end
end
Now use it:
c = City.find(123)
c.locations.only_uniq
It does the same thing as scope or lambda in has_many.

Is it possible to group associations in ruby on rails?

I have a page where I display a list of threads for a user whether the tread was started by them or if they were the recipient of one started.
Here is my model:
has_many :threads_as_starter, :class_name => 'MessageThread', :foreign_key => 'sender_id'
has_many :threads_as_recipient, :class_name => 'MessageThread', :foreign_key => 'recipient_id'
What I'd like to do is define a method that I can store in a in instance variable and loop through on my view page that displays threads of the current_user.
When I run: MessageThread.where( 'sender_id OR recipient_id = ?', 4 )
1.9.3p0 :045 > MessageThread.where( 'sender_id OR recipient_id = ?', 4 )
MessageThread Load (0.4ms) SELECT `message_threads`.* FROM `message_threads` WHERE (sender_id OR recipient_id = 4) ORDER BY message_threads.created_at DESC
=> [#<MessageThread id: 89, message_id: 219, sender_id: 4, recipient_id: 38, status: 0, created_at: "2012-02-15 12:26:17", updated_at: "2012-02-15 12:26:17">, #<MessageThread id: 88, message_id: 218, sender_id: 2, recipient_id: 4, status: 0, created_at: "2012-02-14 13:41:19", updated_at: "2012-02-14 13:41:19">, #<MessageThread id: 87, message_id: 210, sender_id: 1, recipient_id: 2, status: 0, created_at: "2012-02-14 13:31:12", updated_at: "2012-02-14 13:31:12">]
I'm confused as to why it's showing me rows where the sender or recipient id isn't equal to 4.
What query would return all results where the sender_id is 4 but also all the results where the recipient_id is 4? I need to give the signed in user to see a list of all their current threads. Ones that were started by them and ones that weren't.
User A and B only have 1 thread in the message_threads table but either of them can have more threads but with different users but only 1 with each of those users. I use this message_thread table to reference conversations in my messages table where I use the acts_as_tree gem.
There must be a way I can group threads_as_starter and threads_as_recipient e.g. all_threads then call current_user.all_threads to return all.
Thanks in advance
Kind regards
where('sender_id OR recipient_id = ?', 4)
should be
where('sender_id = ? OR recipient_id = ?', 4)
or probably
where('sender_id = ? OR recipient_id = ?', 4, 4)

active record does use all the passed in fields in new/create

I have a website where people can comment and each comment has a category they can pick from the a drop down menue.
In my comment modal I have
belongs_to :category
and I have a category_id in the comment table.
when a user submit the comments in the params I get
params[:comment] = {"locale"=>"en", "body"=>"fds", "category_id" =>2, "from_identifier"=>2130706433, "from_type"=>"ip", "cookie_user_token"=>"130784267178572", "user_id"=>3}
which is exactly what I want. However when I do
Comment.create(params[:comment])
I get
#<Comment id: nil, from_type: "ip", from_identifier: 2130706433, cookie_user_token: 130784267178572, body: "fds", locale: "en", positive_vote_count: 0, adjusted_positive_vote_count: 0.0, negative_vote_count: 0, adjusted_negative_vote_count: 0.0, flag_vote_count: 0, adjusted_flag_vote_count: 0.0, impression_count: 0, visit_count: 0, rank: 137.0, created_at: nil, updated_at: nil, user_id: 3, category_id: nil>
as you can see category_id is nil.
User model has the same relationship with active record, so I don't know why that gets saved and category_id doesn't.
Right now I do
comm = Comment.create(params[:comment])
comm.category_id = params[:comment][:category_id]
Any idea why, and what I should do to avoid the hack up there?
Have you used attr_protected or attr_accessible to prevent mass assignment to category_id?
If so, that's the problem.

Resources