So Im working on a rails app where users can comment on photos or videos another user has uploaded and so far everything is great except I am not able to get the current user_id associated with the person who has commented on the post. This is what I have so far.
user.rb
has_many :comments, :dependent => :destroy
photo.rb
has_many :comments, :as => :commentable
video.rb
has_many :comments, :as => :commentable
comments_controller.rb
def create
#commentable = find_commentable
#comment = #commentable.comments.build(params[:comment])
if #comment.save
redirect_to :id => nil, :notice => "Successfully created comment."
else
render :action => 'new'
end
end
How can I get the user id to appear with the current comments? I have the comment type and comment id I am just looking for a way to have it so the user_id can appear. Any suggestions?
You should add a hidden_field to your form partial where you store the current_user.id
something like:
<%= f.hidden_field :user_id, :value => current_user.id %>
of course you should have a field user_id in your comment model, as a comment belongs_to user and a user has_many comments.
update:
what ofca pointed out, this can approach can lead to security issues as the hidden field could be modified by the user in the browser, e.g. using firebug.
In this case it is probably better to to leave out this field in the view and create the comment in the controller by using
<%= current_user.comments.create(params[:comment]) %>
The way you have it now, it is only set up one way.
Plus you have to make it polymorphic
try adding:
comment.rb
belongs_to :user
belongs_to :commentable, :polymorphic => true
Related
Hi everyone I am new with rails 3,I have a app where I want to associate a idea with a comment.
When I show an idea, in the bottom of the view I show a form to put new comment for this idea, and when a click to save a comment, I have to pass the idea_id, I create my model commment
belongs_to :user
belongs_to :idea
attr_accessible :description, :likes, :name, :user_id, :idea_id
in the view of show idea a put this
= render :partial => "comments/index", :collection => #idea.comments
= render :partial => "comments/form", :locals => {:comment=> #comment}
in the _form of the comment I include idea to obtain idea_id to save
= form_for [#idea, #comment] do |f|
and in my router I put this
resources :ideas do
member do
resources :comments
end
end
and now I obtain this error
undefined method `idea_comments_path'
any idea, anyone knows a document to explain better how to use member in rails!
You don't need member for nested resources:
resources :ideas do
resources :comments
end
http://guides.rubyonrails.org/routing.html
I have two models in Rails 3 - a User model and a Profile model.
class User < ActiveRecord::Base
has_one :profile, :dependent => :destroy
end
class Profile < ActiveRecord::Base
belongs_to :user
end
They are scoped in my routes.rb file, as such:
resources :users do
resources :profiles
end
So now, my form to create a profile reads like this (Using SimpleForm):
<%= simple_form_for([#user, #profile]) do |f| %>
<%= f.error_notification %>
...(Other Inputs)
<% end %>
However, the user ID doesn't seem to be automatically sent to the profile model as I had assumed. Do I have to set that manually through the controller? Or am I missing something?
You should start by making sure that the relationship between User and Profile is indeed working correctly. You've actually put "has_one :user" in your User model, when I think you mean:
class User < ActiveRecord::Base
has_one :profile, :dependent => :destroy
end
In order to send the user ID with the form, the form should be on a page with a URL of something like "localhost:3000/users/5/profiles/new" which you can link to with the helper "new_user_profile_path(5)", for a user with ID 5.
When you submit the form, it will hit the create action in your ProfilesController. The following should result in the creation of the profile:
def create
#user = User.find(params[:user_id])
#profile = #user.build_profile(params[:profile])
#profile.save!
end
add :method => :post to your form since ur html request is GET which should be POST
simple_form_for([#user, #profile], :method => :post) do |f| %>
I'm working on a rails (3.7.8) app and using active admin to manage resources for the ff models:
class AdminUser < ActiveRecord::Base
has_many :user_article_categories, :include => :article_categories
has_many :article_categories, :through => :user_article_categories,
:source => :admin_user
has_many :articles, :through => :user_article_categories,
:source => :admin_user
# ...
end
class UserArticleCategory < ActiveRecord::Base
belongs_to :admin_user
belongs_to :article_category
attr_accessible :admin_user_id, :article_category_id, :included
attr_accessor :included
after_find :set_included
private
def set_included
self.included = "1"
end
# ...
end
the "included" attribute was based on a solution presented here
class ArticleCategory < ActiveRecord::Base
has_many :user_article_categories, :include => :admin_users
has_many :admin_users, :through => :user_article_categories,
:source => :article_category
has_many :articles, :through => :user_article_categories,
:source => :article_category
# ...
end
but I seem not to get setting up (correctly) a form for admin_users, such that creating a new admin_user would have all article_categories displayed as a list of checkboxes
while a persisted admin_user for update would have all article_categories checkboxes displayed but wit all previously set article-categories checked, so that an update would remove unchecked checkboxes and add newly checked ones to what goes to the join-table
for admin/admin_users.rb I create the form as follows, this does not work, though it renders correctly, any help will be appreciated
form do |f|
if f.object.persisted? and current_admin_user.id == f.object.id
f.inputs "Admin Details" do
f.input :email
f.inputs :for => user_article_categories do |usr_art_catr|
usr_art_catr.input :article_category_id, :hidden
usr_art_catr.input :included
end
end
else
f.inputs "Admin Details" do
f.input :email
f.input :superuser, :label => "Super User Priveleges"
f.input :article_categories, :as => :check_boxes,
:collection => ArticleCategory.select("id, name")
end
end
f.buttons
end
Actually, to display a list of checkboxes of all article_categories and check all already checked article categories for a given admin_user on update.
Formtastic, when rendering the show form for the form's object, calls a method provided on the form object via
f.input :method_to_be_called, :as => :checkboxes
which formtastic would compare its result with a collection provided via
the
:collection => any_valid_ruby_object
but both should return the same kinds; array/array or hash/hash, whatever, to determine which checkboxes should be checked, by performing a difference on the two collections.
The method called by formtastic could be an instance method on admin_user that queries the join-table, to determine which checkboxes should be checked and builds an array of that from the related article_categories table or returns an empty array when there is none.
This allows formtastic do what is right, as least in this context. This solution makes the "included" attribute on user_article_categories (the join-table) redundant!
I have a ROR app that has many players, and many proposed games. The games display on a feed and a player can decide to hide them from this feed. The hidden function works like this:
in player.rb:
has_many :hides, :foreign_key=> "hider_id",
:dependent => :destroy
has_many :hidees, :through => :hides
def hidden?(hidee)
hides.find_by_hidee_id(hidee)
end
def hide!(hidee)
hides.create!(:hidee_id => hidee.id)
end
def unhide!(hidee)
hides.find_by_hidee_id(hidee).destroy
end
hides_controller.rb
class HidesController < ApplicationController
def create
#game = Game.find(params[:hide][:hidee_id])
current_profile.hide!(#game)
redirect_to :back
end
def destroy
#game = Hide.find(params[:id]).hidee
current_profile.unhide!(#game)
redirect_to :back
end
end
hide.rb
class Hide < ActiveRecord::Base
attr_accessible :hidee_id
belongs_to :hider, :class_name => "Player"
belongs_to :hidee, :class_name => "Game"
validates :hider_id, :presence => true
validates :hidee_id, :presence => true
end
game.rb
has_many :reverse_hides, :foreign_key => "hidee_id",
:class_name => "Hide",
:dependent => :destroy
has_many :hiders, :through => :reverse_hides
routes.rb
resources :games do
member do
post :publish
post :unpublish
get :view
get :hidees, :hiders
end
I'm trying to do two things: 1. Write a function that would allow me to hide a game from the feed if a relationship between hidden relationship between game and player exits, and 2. write a "show hidden" button that would allow me to return all projects that were "hidden" by the player.
So far with part 1. I have the following code in the view, and while this does the trick in terms of setting up the relationships, it does not "hide" the game from the feed--I'm guessing I would need ajax for that??
- if current_profile.hidden?(game)
= form_for current_profile.hides.find_by_hidee_id(game), :html => { :method => :delete } do |f|
= f.submit "Unhide", :title => "Unhide this game."
- else
= form_for current_profile.hides.build(:hidee_id => game.id) do |f|
= f.hidden_field :hidee_id
= f.submit "Hide", :title => "Hide this game"
Thank you so much for viewing this, I know it's quite long, but I would appreciate any help you could offer. Also, thank you for you time.
the problem I'm having is company_id is not been save to the details table
I know the company_id is there I check it using <%= debug(params[:id])%> on the form before adding all company details information but for some reason is saving everything else but the company_id
##user.rb
has_one :company
##company.rb
belongs_to :user
has_one :detail
##detail.rb
belongs_to :user
##details controller
def new
#detail = Detail.new
user_id = session[:user_id]
company_id = params[:id]
end
def create
#detail = Detail.new(params[:detail])
#detail.user_id = session[:user_id]
#detail.company_id = params[:id]
end
###settings.html.erb
### this is where i make sure that company_id gets pass with the url
link_to 'New Detail', {:controller => 'details', :action =>'new', :id => company.id }, :class => 'plus'
#####routes
resources :details
resources :companies
resources :users
resources :sessions
I know this may not look pretty or proper if you know a better way please let me know...thanks in advance.
I notice something immediately. You may need to fix your associations first. Assuming, a user has one company and a company has one detail.
##user.rb
has_one :company
##company.rb
belongs_to :user
has_one :detail
##detail.rb
belongs_to :user
Should be:
##user.rb
has_one :company
##company.rb
belongs_to :user
has_one :detail
##detail.rb
belongs_to :company
Although, depending on your domain requirements. I would normally have it as: User has_many Companies. And since details is 1:1 with company, I would include all the details inside company.
I didn't realize this until later but I need it pass values to from on the view to the from like so
<% #companies.each do |company| %>
<%= link_to 'New Detail', {:controller =>'details', :action => 'new', :company_id => company.id}, :class => 'plus' %>
<% end %>
and I need it to collect that value on the from...like so
<%= form_for(:detail, :url =>{:action => 'create', :company_id => #company.id}) do |f| %>
...(values)
<% end %>