I am working on very simple application for managing user projects. There are two models, User and Project. User should view only projects they created. So, model Project has user_id column for linking with User. Models:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable, :rememberable, :validatable
has_many :projects, :dependent => :destroy
attr_accessible :email, :password, :password_confirmation, :remember_me
end
class Project < ActiveRecord::Base
belongs_to :user
end
When user creates new project, user id should be automatically added to user_id column. This is accomplished in Project controller under create action:
def create
params[:project][:user_id] = current_user.id
#project = Project.new(params[:project])
#...
This works when I add user_id to params[:project] but I have a feeling this is not a proper way to do is. Or is it?
def create
#project = current_user.projects.build(params[:project])
#...
http://guides.rubyonrails.org/association_basics.html#has_many_collection_build
Related
I am currently building very simple Comment system on Rails. The primary models are User, Albumpost, and Comment. Users can post Albumposts. For each Albumpost, Users can add Comments to the Albumpost. As a result, a Comment belongs to a User and belongs to an Albumpost.
The problem I'm having is that even with the proper associations in my models (see below), I can't get
#comment.user.name
when I'm trying to render the comments in the albumpost 'show' page (/views/albumposts/show.html.erb). When I go to the page, I can't get #comment.user.name (doesn't understand the association) and get a
"undefined method `name' for nil:NilClass"
Oddly I can get
#comment.albumpost.content
I've double-checked my models and also added the proper foreign keys to the models. Am I doing something wrong in the controllers?
Here are my models:
class Comment < ActiveRecord::Base
attr_accessible :body, :albumpost_id, :user_id
belongs_to :albumpost
belongs_to :user
end
class Albumpost < ActiveRecord::Base
attr_accessible :content
belongs_to :user
has_many :comments, dependent: :destroy
end
class User < ActiveRecord::Base
attr_accessible :name, :email, :password, :password_confirmation
has_many :albumposts, dependent: :destroy
has_many :comments, dependent: :destroy
end
Here are the relevant parts of my Albumpost and Comments controllers:
class AlbumpostsController < ApplicationController
def show
#albumpost = Albumpost.find(params[:id])
#comments = #albumpost.comments
#comment = Comment.new
#comment.albumpost_id = #albumpost.id
#comment.user_id = current_user.id
end
end
class CommentsController < ApplicationController
def create
albumpost_id = params[:comment].delete(:albumpost_id)
#comment = Comment.new(params[:comment])
#comment.albumpost_id = albumpost_id
#comment.user_id = current_user.id
#comment.save
redirect_to albumpost_path(#comment.albumpost)
end
end
I think you should prefer setting objects to relations instead of setting their ids. For example, you should do this:
#comment.user = current_user
instead of
#comment.user_id = current_user.id
ActiveRecord will take care of setting corresponding *_id fields. I'm not sure how it handles the reverse. (it should autoload though, if I understand correctly)
I have Two models Users and Profiles ( Users is from devise ). A user can have many profiles , so i created a migration to add user_id to Profiles.
class Profile < ActiveRecord::Base
belongs_to :user
attr_accessible :description, :name, :product, :image, :price , :user_id
mount_uploader :image, ImageUploader
validates_presence_of :name, :product,:image, :price
end
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me
# attr_accessible :title, :body
has_many :profiles
validates_associated :profiles
end
In my profiles controller , i have a new method to create a new profile. I want that when user logs in, he is able to see only his profiles not all.
def new
#profile = current_user.profiles.build
##profile = #user.profile.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #profile }
end
end
Ideally, my user_id column should be updated with build, but my user_id does not get updated and that is why profiles are not displayed . i am using postgresql with pg gem and when i manually add the user_id for that profile , i am able to see the profiles.
Please help to solve this, i am able to figure this out since a long time.Let me know if you want more information to solve this.
Maybe try something like this in your controller:
if current_user.profiles.count == 0
profile = Profile.create
current_user.profiles << profile
end
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
I have a method that works locally on my machine but it fails in Heroku. Heroku logs say:
NoMethodError (undefined method `events' for nil:NilClass)
I have used heroku console for an equivalent of this method and it works so there is data that supports it. The method is:
def index
#events = current_user.school.events
end
I am using Devise which I believe gives me the current_user method. The equivalent, a = User.first.school.events yields the true instance value with data. The User.first yields correct data.
Here are my models:
class School < ActiveRecord::Base
#validates_presence_of :name
has_many :events, :dependent => :destroy
has_many :users, :dependent => :destroy
belongs_to :user
belongs_to :event
def self.fetch_for_name(_name)
school = self.new(:name => _name)
end
end
class User < ActiveRecord::Base
belongs_to :school
rolify
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessible :name, :email, :password, :password_confirmation, :remember_me
end
class Event < ActiveRecord::Base
belongs_to :school
end
It would be like me if I overlooked some simple, basic thing but if I can do this correctly in Heroku console, why would this method break. Another unrelated page works correctly on Heroku.
current_user is the user that is logged in. It doesn't necessarily mean User.first. This should be the same locally as on Heroku. If you're having trouble figuring out what user is logged in you can add this to your application controller
before_filter :debug
def debug
Rails.logger.info("Current User is: #{current_user.inspect}")
end
And then view the output with $ heroku logs --tail It should show you the current value of the current_user. At the end of the day what #thesis said is correct, you have a user that does not have a school associated with it.
I have 3 models: Users, Customers, Issues. Below is the code for these models
Customer model:
class Customer < ActiveRecord::Base
belongs_to :se
belongs_to :user
has_many :issues
end
Issues model:
class Issue < ActiveRecord::Base
belongs_to :customer
end
Users model:
class User < ActiveRecord::Base
has_many :ses
has_many :customers
has_many :issues, :through => :customers
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessible :email, :password, :password_confirmation, :remember_me, :first_name, :last_name, :cell_ph, :area
end
I would like to display only the issues that belong to a particular user. I am having problems making this work. Can someone suggest how I might create an index method that would accomplish this?
Here is my index method where I'm trying to use devise's current_user method to identify the user who's logged in to the view:
def index
#issues = Issue.where(:user == :current_user)
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #issues }
end
end
You can't do what you're doing because an Issue doesn't have a user.
According to Rails guides (second example on http://guides.rubyonrails.org/association_basics.html#the-has_many-through-association session), you can nest the has_many using a has_many :through.
So you should be able to do this:
current_user.issues
In addition to Rodrigo's answer, you have some bad syntax on this line:
#issues = Issue.where(:user == :current_user)
That's never going to return any results because :user == :current_user is performing a comparison of two distinct Ruby Symbol objects. That always returns false, so your statement essentially equates to Issue.where(false).
This is closer to what you need:
#issues = Issue.where(:user => current_user)
This still doesn't fix the problem you have (Issue does not have many Users), but at least the meaning is correct.