Rails3 ActiveRecord, 2 level result access - ruby-on-rails-3

I have some AR models
User
has_many :clients, :through => :users_to_clients
has_many :files
Client
has_many :users_to_clients
has_many :users, :through => :users_to_clients
has_many :files
File
belongs_to :client
belongs_to :user
and try to fetch all files, trough clients assigned to user
u = User.includes(:clients => :xls_files).find(1)
This code fire 3 sql query. In final sql looks like what i need he fecth all files trough clients on user.
SELECT "files".* FROM "files" WHERE "files"."client_id" IN (1, 2)
but how to get this data, if u variable just contain User object?

Try this
User
has_many :files
has_many :clients, :through => :files
Client
has_many :files
has_many :users, :through => :files
File
belongs_to :users
belongs_to :clients
Then you can do stuff like #user.clients and #client.users
I can't tell from your post, but you may have to switch the client and file models around, so client belongs to users and files, depending on your situation.

I don't find any solution so i made it by hand by adding scope in File model
scope :by_user_clients, lambda { |user| where(client_id:
user.clients.pluck(:id)) }
File.by_user_clients(#user)

Related

How can I reference the same model twice and create the association in a multiple select form?

I have two classes (Game and Report) and want to link them with an additional attribute (default = yes or no).
The game should then have default_reports and optional_reports.
The association is then updated by selecting the default and optional reports in a select (multiple) in the games create/edit form.
I have tried using has_many and through as well as polymorphic associations, but nothing seems to fit the use case, where the associated objects are fixed and you only want to manage associations.
class Game < ActiveRecord::Base
has_many :game_reports
has_many :reports, :through => :game_reports
end
class Report < ActiveRecord::Base
has_many :game_reports
has_many :games, :through => :game_reports
end
class GameReport < ActiveRecord::Base
belongs_to :game
belongs_to :report
end
Any help is appreciated!
Thanks
this is just the model. the view and form to create the records is an entirely different matter.
you can always add a conditions option to has_many. I'm assuming you're going to add default to game_reports so change your class to something like.
class Game < ActiveRecord::Base
has_many :game_reports
has_many :reports, :through => :game_reports
has_many :default_reports, through: :game_reports, source: :report, conditions: { game_reports: { default: true } }
end
Rails 4.2+, use a Polymorphic association with scope and specify the foreign_key and foreign_type options.
class GameReport
belongs_to :report, :polymorphic => true
end
class Game
has_many :game_reports, :as => :report, :dependent => :destroy
has_many :reports, -> { where attachable_type: "GameReport"},
class_name: GameReport, foreign_key: :game_report_id,
foreign_type: :game_report_type, dependent: :destroy
end
Other approachs:
Rails Polymorphic Association with multiple associations on the same model

How to get single attribute from array in a has_many :through association (User/Friend model)

In my User model I have the following:
class User < ActiveRecord::Base
has_many :friendships, dependent: :destroy
has_many :friends, :class_name => "User", :foreign_key => "friend_id"
has_many :pending_friends,
:through => :friendships,
:conditions => "status = 'pending'",
:foreign_key => "user_id",
:source => :friend
has_many :requested_friends,
:through => :friendships,
:source => :friend,
:conditions => "status = 'requested'"
def friends
direct_friends | inverse_friends
end
In my Friendship model I have the following:
class Friendship < ActiveRecord::Base
belongs_to :user
belongs_to :friend, :class_name => "User", :foreign_key => "friend_id"
In my view I have created an array of each of the users' friends, shown below. This code works and populates the array with all the data from the friends' "User" database model attributes.
User.first.friends
However, I want to be able to call the users' friend's name's. So, for example, shouldn't I be able to do something like this?
User.first.friends.map(&:name)
How do I get an array containing just the friend's name's, instead of all the friend's user attributes? I would also appreciate if anyone could tell me why .first is used (I got that from here: Rails calling User record from Friends model), as it doesn't just get the first instance of the User's friends (it gets all the instances). And why does just doing:
User.friends
return an empty array?
Try method pluck:
User.first.friends.pluck(:name)
You should use first method to retrieve one object from table. The User is table with a lot of users.

What's the rails way to include a field in a join model when listing an association?

So if I have the following relationship
class Item < ActiveRecord::Base
has_many :item_user_relationships
has_many :users, :through => :item_user_relationships
end
class User < ActiveRecord::Base
has_many :item_user_relationships
has_many :items, :through => :item_user_relationships
end
class ItemUserRelationship < ActiveRecord::Base
belongs_to :item
belongs_to :user
attr_accessible :role
end
What's the rails way to include the role attribute when listing all the Users of an Item?
#users = #item.users # I want to include the role as part of a user
Thanks!
UPDATE: I'm still having trouble with this. My goal is to get an array of User models that have their role included in the attributes.
I'm note sure if I understand you correctly, but maybe this is what you want?
#users = #item.users
#users.each do |user|
puts user.item_user_relationships.first.role
end

Find rows with same some_attribute but two different values for user_id

These are my classes & relations
class User
has_many :conversation_participants
has_many :conversations, :through => :conversation_participants
end
class ConversationParticipant
belongs_to :user
belongs_to :conversation
end
class Conversation
has_many :messages
has_many :conversation_participants
has_many :users, :through => :conversation_participants
end
So when I want to create a conversation between user_ids 12 and 15, I first want to check if a conversation between these two already exists. So what I need to find is this:
ConversationParticipants where user_id IN (12, 15) AND "both conversationparticipant rows have the same conversation id"
I lack the proper words to explain this query but I think everyone will get what I mean. "Does a conversation between these two users exist already?". I know neither how to do it in SQL nor Rails so any answer is appreciated.
EDIT
The id of the conversation would not be known. I need to find if a conversation between those two user_ids exist.
Thanks
-- Emil
class User
has_many :conversations
has_many :conversation_participants
has_many :joined_conversations, :through => :conversation_participants, :source => :conversation
end
class ConversationParticipant
belongs_to :user
belongs_to :conversation
end
class Conversation
belongs_to :user
has_many :conversation_participants
has_many :speakers, :through => :conversation_participants, :source => :user
end
You can try this
#result = ConversationParticipants.where("user_id in ? AND conversation_id=?",[1,2,3,4],2)

Rails 3 - Nested Form and has_many through association

Hi people, long time not been here. But I'm back because I need your help again please. I have a rails 3.0.9 app, and I'm working with nested forms and has_many through association. When i create an instance, it works great. The problems come when I try to edit. Here is an example for a better explanation. (table names and attributes are just for explaining)
Table Client
id
company_name
address
Table Worker
id
first_name
last name
Table Contact
id
client_id
worker_id
my models looks like these
class Worker < ActiveRecord::Base
has_many :contacts, :dependent => :destroy
has_many :clients, :through => :contacts, :foreign_key => 'client_id'
end
class Client < ActiveRecord::Base
has_many :contacts, :foreign_key => "client_id",:dependent => :destroy
has_many :workers, :through => :contacts, :foreign_key => 'worker_id'
accepts_nested_attributes_for :workers, :allow_destroy => false
end
class Contact < ActiveRecord::Base
belongs_to :worker, :foreign_key => "worker_id"
belongs_to :client, :foreign_key => "client_id"
end
Then in my form for create a client, I can create many workers, and rails make the association and creates the instances for the contacts table (by using nested forms).
The thing is, if I want to edit a client by removing a contact, the contact is not removed. As you can see I put this line in the clients model
accepts_nested_attributes_for :workers, :allow_destroy => false
I set the allow_destroy to false, because I don't want to delete the worker itself, I just want to remove the contact tuple.
Does anybody know how can I solve this?? Hope you can help me... Thanks