polymorphic association belongs to User - ruby-on-rails

I have a comments model which is a polymorphic association which is involved with Statuses and Photos. How can I create this polymorphic association to also belong to a User so that when a user creates a comment under statuses or photos it will also recieve the current_user id?
this is what I have as of now-
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
belongs_to :user
end
class User < ActiveRecord::Base
has_many :comments
end
class Status < ActiveRecord::Base
has_many :comments, as: :commentable
end
class Photo < ActiveRecord::Base
has_many :comments, as: :commentable
end
just to reiterate, how can I create a comment as a user but also have it under status or photo? it would need the user_id.
This is where I am having the trouble-
how should I set this up?
def create
#comment = #commentable.comments.new(comments_params)
if #comment.save
redirect_to #commentable, notice: "Comment created"
else
render :new
end
end

Try this
class Comment < ActiveRecord::Base
belongs_to :likable, :polymorphic => true
belongs_to :commentable, :polymorphic => true
belongs_to: user
class User < ActiveRecord::Base
has_many :statuses, :as => :likable
has_many :photos, :as => :commentable
has_many :comments
class Status < ActiveRecord::Base
has_many :comments, :as => :likable, :dependent => :destroy
class Photos < ActiveRecord::Base
has_many :comments, :as => :commentable, :dependent => :destroy

It's a little bit hacky but I found a workaround. So in my CommentsController i did this:
def create
new_params = comments_params
new_params[:user_id] = current_user.id
#comment = #commentable.comments.build(new_params)
if #comment.save
redirect_to #commentable, notice: "Comment created"
else
render :new
end
end
that placed the user_id which is what I needed.

Related

How to apply association rules

I'm confusing about association.
I tried to write code below but rails was returned me "undefined method `subs'".
def show
#product = Product.find(params[:id])
#materials = #product.materials.subs
respond_to do |format|
format.json { render json: [ #product,#materials ]}
end
end
I want Product model relates to Sub model and I get Sub model record.
If someone knows about this problem to solve please tell me.
class Product < ActiveRecord::Base
has_many :product_materials
has_many :materials, :through => :product_materials
end
class ProductMaterial < ActiveRecord::Base
belongs_to :product
belongs_to :material
end
class Material < ActiveRecord::Base
has_many :product_materials
has_many :products, :through => :product_materials
has_many :material_subs
has_many :subs, :through => :material_subs
end
class MaterialSub < ActiveRecord::Base
belongs_to :material
belongs_to :sub
end
class Sub < ActiveRecord::Base
has_many :material_subs
has_many :materials, :through => :material_subs
end
#product.materials is an array and you cannot chain a association on an array
#product = Product.includes(materials: :subs).find(params[:id])
#materials = #product.materials.flat_map(&:subs)
this will loop over the materials and will return subs for each material

How to save has_many :through self-referencial association

I've set up a self-referencial association using has_many :through, basically as described on this Railscast: http://railscasts.com/episodes/163-self-referential-association.
Some "activities" act kinda like "articles" and have an associated set of other activities, hence the naming of the join table. It is a little confusing... I know.
I am having a tough time getting things to save right. Here is what I've got...
activity.rb
class Activity < ActiveRecord::Base
has_many :article_activities
has_many :activities, :through => :article_activities
accepts_nested_attributes_for :activities
end
article_activity.rb
class ArticleActivity < ActiveRecord::Base
attr_accessible :article_id, :activity_id
belongs_to :activity
belongs_to :article, :class_name => "Activity"
end
articles_controller.rb
class ArticlesController < ApplicationController
def new
#activity = Activity.new
#activity.is_article = true
#user_activities = current_user.activities
end
def create
#activity = Activity.new params[:activity]
#activity.is_article = true
#activity.user = current_user
if #activity.save
redirect_to root_path, :notice => "Article created!"
else
render :action => "new"
end
end
new.html.haml
= simple_form_for #activity, :url => articles_path do |f|
/ Other fields omitted for clarity
= f.association :activities, :collection => #user_activities
So, upon submitting the form, #activity in the create action has the expected #activity.activities. However, upon saving #activity and reloading the record, #activity.activities is empty.
Any ideas how to save the associations?
I figured this one out. I had to add a :foreign_key for "article" to the models...
class ArticleActivity < ActiveRecord::Base
attr_accessible :article_id, :activity_id
belongs_to :activity
belongs_to :article, :class_name => "Activity", :foreign_key => "article_id"
end
class Activity < ActiveRecord::Base
belongs_to :user
has_many :article_activities, :foreign_key => "article_id"
has_many :activities, :through => :article_activities
end

Rails 3.2 Nested Form Custom Foreign Key Unable to Save

I have this Reviews Model:
class Review < ActiveRecord::Base
attr_accessible :approved, :reviewed_id, :for, :user_id, :text, :rating, :title
belongs_to :business
belongs_to :product
end
and this Product model:
class Product < ActiveRecord::Base
include ApplicationHelper
belongs_to :business
belongs_to :catalog
belongs_to :category
has_many :reviews, :foreign_key => :reviewed_id
has_many :features, :dependent => :destroy
end
and this Business model:
class Business < ActiveRecord::Base
validates_presence_of :name
validates_presence_of :category
mount_uploader :photo, PhotoUploader
has_many :catalogs, :dependent => :destroy
has_many :products, :dependent => :destroy
has_many :branches, :dependent => :destroy
has_many :reviews, :foreign_key => :reviewed_id
end
but with this create action in the Reviews controller:
def create
#business = Business.find(params[:business_id])
if params.has_key?('product_id')
#product = Product.find(params[:product_id])
#review = #product.reviews.build(params[:review])
if #review.save
flash[:notice] = 'Pending Review Submitted'
redirect_to business_product_path(#business, #product)
else
#form_resources = [#business, #product, #review]
respond_with(#business, #product, #review)
end
else
#review = #business.reviews.build(params[:review])
if #review.save
flash[:notice] = 'Pending Review Submitted'
redirect_to business_path(#business)
else
#form_resources = [#business, #review]
respond_with(#business, #review)
end
end
end
I can't save the association. simple_form says there is an error, but I can't see the error in my logs, and all the other fields are validated so I'm guessing there is a problem with the association.
SIDE QUESTION: how can you I make simple_form show all errors?
fixed it by using polymorphic associations and getting rid of for and reviewed_id in the reviews model. refer here:
http://guides.rubyonrails.org/association_basics.html#polymorphic-associations

Delete something through relationship table

i have 4 models. I want to delete question, but now i cant. Dont why know. I think, firstly i need delete answer on this questions, then delete inquiry, and then questions itself. Right. But how i can do it?
there my models:
-respondents_model
class Respondent < ActiveRecord::Base
has_many :inquiries
has_many :questions, :through => :inquiries
has_many :answers, :through => :inquiries
end
-answer_model
class Answer < ActiveRecord::Base
belongs_to :inquiry
belongs_to :question
validates_uniqueness_of :inquiry_id
end
-question_model
class Question < ActiveRecord::Base
has_one :answer, :through => :inquiry , :dependent => :destroy
belongs_to :inquiry , :dependent => :destroy
end
-inquiry_model
class Inquiry < ActiveRecord::Base
belongs_to :question
belongs_to :respondent
has_one :answer
end
and my question_controller
def destroy
#question.destroy
head :ok
end
You don't need to delete answers, because they will be automatically deleted as far as you set :dependent => :destroy. So you just need to call:
Also you need to specify WHAT EXACT question are you going to destroy: Question.find params[:id]
def destroy
#question = Question.find params[:id]
#question.destroy
head :ok
end

Passing two variables to separate table...associations problem

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

Resources