Ok, I am trying to display the profile pic of a user. The application I have set up allows users to create questions and answers (I am calling answers 'sites' in the code) the view in which I am trying to do so is in the /views/questions/show.html.erb file. It might also be of note that I am using the Paperclip gem. Here is the set up:
Associations
Users
class User < ActiveRecord::Base
has_many :questions, :dependent => :destroy
has_many :sites, :dependent => :destroy
has_many :notes, :dependent => :destroy
has_many :likes, :through => :sites , :dependent => :destroy
has_many :pics, :dependent => :destroy
has_many :likes, :dependent => :destroy
end
Questions
class Question < ActiveRecord::Base
has_many :sites, :dependent => :destroy
has_many :notes, :dependent => :destroy
has_many :likes, :dependent => :destroy
belongs_to :user
end
Answers (sites)
class Site < ActiveRecord::Base
belongs_to :question
belongs_to :user
has_many :notes, :dependent => :destroy
has_many :likes, :dependent => :destroy
has_attached_file :photo, :styles => { :small => "250x250>" }
end
Pics
class Pic < ActiveRecord::Base
has_attached_file :profile_pic, :styles => { :small => "100x100" }
belongs_to :user
end
The /views/questions/show.html.erb is rendering the partial /views/sites/_site.html.erb which is calling the Answer (site) with:
<% div_for site do %>
<%=h site.description %>
<% end %>
I have been trying to do things like:
<%=image_tag site.user.pic.profile_pic.url(:small) %>
<%=image_tag site.user.profile_pic.url(:small) %>
etc. But that is obviously wrong. My error directs me to the Questions#show action so I am imagining that I need to define something in there but not sure what. Is is possible to call the pic given the current associations, placement of the call, and if so what Controller additions do I need to make, and what line of code will call the pic?
UPDATE: Here is the QuestionsController#show code:
def show
#question = Question.find(params[:id])
#sites = #question.sites.all(:select => "sites.*, SUM(likes.like) as like_total",
:joins => "LEFT JOIN likes AS likes ON likes.site_id = sites.id",
:group => "sites.id",
:order => "like_total DESC")
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #question }
end
end
You have has_many association for the pics:
class User < ActiveRecord::Base
...
has_many :pics, :dependent => :destroy
end
But you are trying to act, as if there was only one pic:
<%=image_tag site.user.pic.profile_pic.url(:small) %>
So either take first picture (probably you should also check if it exists) :
<%=image_tag site.user.pics.first.profile_pic.url(:small) %>
Or change the association to has_one if user can have only one picture:
class User < ActiveRecord::Base
...
has_one :pic, :dependent => :destroy
end
<%=image_tag site.user.pic.profile_pic.url(:small) %>
Related
i'm breaking my head to get the user of this situation:
a conversation model:
has_many :conversation_participants, :dependent => :destroy
has_many :users,
:through => :conversation_participants
has_many :messages, :dependent => :destroy
has_one :display_message,
:class_name => 'Message',
:order => 'created_at DESC'
def participants(options={})
if options[:not].is_a? User
users - [options[:not]]
else
users
end
end
and conversation_participants:
belongs_to :user
belongs_to :conversation
attr_accessible :user_id
on a conversation helper:
def self_or_other
#conversation.conversation_participants.find_by_user_id(:not => current_user)
end
please, someone could clear me how to get the other user inside conversation_participants model?
I believe like follows:
#conversation.conversation_participants.where.not(user_id: current_user.id).first
So basically, my app contains users (model User) who have friends (unilateral access), and who also own lists.
What I'm trying to achieve here is when creating a new list, to provide it with "accessors", picked from the user's friends.
My code is heavily inspired from the following railscast on virtual attributes.
So, here comes my User and UserAccessor model (just the relevant parts) :
class User < ActiveRecord::Base
has_many :lists, :dependent => :destroy
has_many :friendships, :dependent => :destroy
has_many :friends, :through => :friendships
end
class UserAccessor < ActiveRecord::Base
belongs_to :accessor, :class_name => "User"
belongs_to :accessible_list, :class_name => "List"
end
My List model :
class List < ActiveRecord::Base
has_many :items
belongs_to :user
has_many :user_accessors, :foreign_key => "accessible_list_id", :dependent => :destroy
has_many :accessors, :class_name => "User", :through => :user_accessors
validates :title, :presence => true, :length => { :minimum => 1 }
attr_writer :authorized_users
after_save :add_accessors
def authorized_users
#authorized_users || self.accessors.map(&:username).join(' ')
end
private
def add_accessors
if #authorized_users
accessors = #authorized_users.split(' ').map do |username|
user = User.find_by_username(username)
if user
if self.user.inverse_friends.include? user
self.user_accessors.build(:accessor_id => user.id).accessor
end
end
end
end
end
end
The form used to create or update the list is the following one :
= simple_form_for [#user, #list] do |f|
= f.input :title, :label => "Titre"
= f.input :authorized_users, :label => "Authorized users", :hint => "Separated by spaces"
%p
= f.button :submit
So my problem comes from the fact that I don't know exactly how to create/update the accessors, my code self.user_accessors.build(:accessor_id => user.id).accessor definitely not working to fill it correctly.
I'm still quite a noob in rails (and ruby in general…), so I hope what I put there was relevant enough for you to help me! Thanks in advance!
I have a Post model:
class Post < ActiveRecord::Base
belongs_to :user
has_many :taggings, :dependent => :destroy
has_many :tags, :through => :taggings
attr_writer :tag_names
after_save :assign_tags
before_create :init_sort_column
def tag_names
#tag_names || tags.map(&:name).join(" ")
end
private
def assign_tags
self.tags = []
return if #tag_names.blank?
#tag_names.split(" ").each do |name|
tag = Tag.find_or_create_by_name(name)
self.tags << tag unless tags.include?(tag)
end
end
end
a Tag model:
class Tag < ActiveRecord::Base
has_many :taggings, :dependent => :destroy
has_many :posts, :through => :taggings
has_many :subscriptions
#has_many :subscribed_users, :source => :user, :through => :subscriptions
end
and a User model:
class User < ActiveRecord::Base
(Code related to Devise)
has_many :posts, :dependent => :destroy
has_many :subscriptions
has_many :subscribed_tags, :source => :tag, :through => :subscriptions
has_many :subscribed_posts, :source => :posts, :through => :subscribed_tags
attr_writer :subscribed_tag_names
after_save :assign_subscribed_tags
def subscribed_tag_names
#subscribed_tag_names || subscribed_tags.map(&:name).join(' ')
end
private
def assign_subscribed_tags
#self.subscribed_tags = []
return if #subscribed_tag_names.blank?
#subscribed_tag_names.split(" ").each do |name|
subscribed_tag = Tag.find_or_create_by_name(name)
self.subscribed_tags << subscribed_tag unless subscribed_tags.include?(subscribed_tag)
end
end
end
In the index page users only see posts with tags they have subscribed to:
posts_controller.rb:
#posts = current_user.subscribed_posts.paginate(:page => params[:page],
:per_page => 5,
:order => params[:order_by])
Now say there is a post with the tags food and drinks, and the user has subscribed to these two tags. He will see the post twice; it seems like it is appearing once as a post tagged as food and then as a post tagged as drinks.
Is there a way of preventing posts like this from appearing twice?
Add :uniq => true as a parameter to the has_many in the User model:
has_many :subscribed_posts, :source => :posts, :through => :subscribed_tags, :uniq => true
The docs at http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many-label-Options says:
:uniq
If true, duplicates will be omitted from the collection. Useful
in conjunction with :through.
My has_many :through associations on Releases/Products/Tracks seem to be deleting the the Track and leaving orphaned associations in the releases_tracks / products_tracks tables. I can't see where i've gone wrong, I thought the default behavior is to delete the association only. Can anyone help please?
My Models:
class Track < ActiveRecord::Base
has_many :releases_tracks
has_many :tracks, :through => :releases_tracks
has_many :products_tracks
has_many :products, :through => :products_tracks
end
class Release < ActiveRecord::Base
has_many :releases_tracks
has_many :tracks, :through => :releases_tracks
end
class Product < ActiveRecord::Base
has_many :products_tracks
has_many :tracks, :through => :products_tracks
before_save do
self.track_ids = self.releases_track_ids
end
end
class ProductsTrack < ActiveRecord::Base
belongs_to :product
belongs_to :track
end
class ReleasesTrack < ActiveRecord::Base
belongs_to :release
belongs_to :track
end
My Track Controller (for the destroy action):
class TracksController < ApplicationController
before_filter :get_track_parent
def destroy
#track = #parent.tracks.find(params[:id])
#track.destroy
redirect_to #parent
end
private
def get_track_parent
if params[:product_id].present?
#parent = Product.find(params[:product_id])
elsif params[:release_id].present?
#parent = Release.find(params[:release_id])
end
end
end
My destroy link in the releases view:
<%= link_to image_tag("icons/delete.png"), release_track_path(#release,track), :confirm => 'Are you sure?', :method => :delete %>
And finally, my destroy link in the products view:
<%= link_to image_tag("icons/delete.png"), product_track_path(#product,track), :confirm => 'Are you sure?', :method => :delete %>
First of all, you need :dependent => :destroy option for your associations:
class Track < ActiveRecord::Base
has_many :releases_tracks, :dependent => :destroy
has_many :releases, :through => :releases_tracks # also note you had here :tracks instead of :releases
has_many :products_tracks, :dependent => :destroy
has_many :products, :through => :products_tracks
end
And also if you want tracks to be removed when removing releases or products, add following :dependent => :destroys:
class Release < ActiveRecord::Base
has_many :releases_tracks, :dependent => :destroy
has_many :tracks, :through => :releases_tracks
end
class Product < ActiveRecord::Base
has_many :products_tracks, :dependent => :destroy
has_many :tracks, :through => :products_tracks
before_save do
self.track_ids = self.releases_track_ids
end
end
class ProductsTrack < ActiveRecord::Base
belongs_to :product
belongs_to :track, :dependent => :destroy
end
class ReleasesTrack < ActiveRecord::Base
belongs_to :release
belongs_to :track, :dependent => :destroy
end
I have developed an application and I seem to be having some problems with my associations. I have the following:
class User < ActiveRecord::Base
acts_as_authentic
has_many :questions, :dependent => :destroy
has_many :sites , :dependent => :destroy
end
Questions
class Question < ActiveRecord::Base
has_many :sites, :dependent => :destroy
has_many :notes, :through => :sites
belongs_to :user
end
Sites (think of this as answers to questions)
class Site < ActiveRecord::Base
acts_as_voteable :vote_counter => true
belongs_to :question
belongs_to :user
has_many :notes, :dependent => :destroy
has_many :likes, :dependent => :destroy
has_attached_file :photo, :styles => { :small => "250x250>" }
validates_presence_of :name, :description
end
When a Site (answer) is created I am successfully passing the question_id to the Sites table but I can't figure out how to also pass the user_id. Here is my SitesController#create
def create
#question = Question.find(params[:question_id])
#site = #question.sites.create!(params[:site])
respond_to do |format|
format.html { redirect_to(#question) }
format.js
end
end
I'd think this would do the job
#question = current_user.questions.find params[:question_id]
if not, then just assign mannualy.
#site = #question.sites.build(params[:site])
#site.user = current_user
#site.save