How to link/add models to each other - ruby-on-rails

I'm trying to add idea(s) to a user. So far I added has_many to my user and belongs_to to my idea. And I added a foreign key to User using:
rails g migration Add_User_id_To_Ideas user_id:integer
Now, how do I assign the idea to the specific user, when a user creates a new idea?
I tried to work parallel to this example, but I'm a bit stuck.
user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :ideas
end
idea.rb
class Idea < ActiveRecord::Base
belongs_to :user
has_many :comments
mount_uploader :picture, PictureUploader
# {attr_accessor :Status}
enum status: [ :Draft, :Published]
end

Several ways to do this, but I think the most straight forward way would be to save the user_id in the ideas controller create action.
# def create inside ideas_controller
#idea.user_id = current_user.id
if #idea.save
# etc
Couple other options are a hidden field or before_save callback. Here's an example of passing through a hidden field. In your #idea form:
<%= f.hidden_field :user_id, value: current_user.id %>
This will add user_id to the params being saved. Make sure that :user_id is whitelisted in the permitted params at the bottom of your ideas controller.
To permit user_id in idea_params:
def idea_params
params.require(:idea).permit(:user_id, :also_add_other_params)
end

Related

attr_accessor does not work on associated objects that aren't saved

I haven't been able to find an explanation as to why attr_accessor works here:
fb_profile = FbProfile.where(identifier: params[:identifier]).first_or_initialize
fb_profile.signed_request = "randomstring"
logger.info(fb_profile.signed_request) # outputs "randomstring"
but not here:
current_admin.fb_profile = FbProfile.where(identifier: params[:identifier]).first_or_initialize
current_admin.fb_profile.signed_request = "randomstring"
logger.info(current_admin.fb_profile.signed_request) # outputs undefined
I can work like in the first example, but then I have to create the association later, which seems dirtier than just creating it from the get go. Is this common behavior?
Update1:
As some requested, here are the relevant parts of both models:
class Admin < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:confirmable, :omniauthable
include DeviseTokenAuth::Concerns::User
has_one :fb_profile
end
class FbProfile < ApplicationRecord
belongs_to :admin
has_and_belongs_to_many :fb_pages
attr_accessor :signed_request
end
You're missing the relation between current_admin and fbprofile.
If you've a has_one relation I would write something like this :
current_admin.fb_profile ||= current_admin.build_fb_profile(identifier: params[:identifier])

Rails Trying to create a profile after the user has been created

I'm trying to figure out how to create a new profile for the user that has just been created,
I'm using devise on the User model, and the User model has a one to one relationship with the UserProfile model.
Here's what my User Model looks like:
class User < ActiveRecord::Base
has_and_belongs_to_many :roles
belongs_to :batch
has_one :user_profile
after_create :create_user_profile
def create_user_profile
self.user_profile.new(:name => 'username')
end
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
This generate the following error:
undefined method `new' for nil:NilClass
i've tried User.find(1).user_profile in rails c and that works so I'm pritty sure the relationship is setup correctly,
I'm probably being a big fat noob and trying to fetch self incorrectly.
plus can you also tell me how to access the params in a Model... is that even possible?
A has_one relationship will automatically add the :create_<relationship> and build_<relationship> methods. Checkout the rails guide.
You could try this:
after_create do
create_user_profile(:name => 'username')
end
Or more likely
after_create do
create_user_profile(:name => self.username)
end

Get variable from another table in ROR models

I am trying to get a user who has not filled out their profile to redirect to the edit page.
I have two tables - Users (Devise handles) and Profiles.
Profiles has a row called profile_complete
In my user model I am trying to define a method called profile_complete which takes the boolean of profiles_complete and passes it back.
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :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
has_many :profiles, :dependent => :destroy
def profile_complete?
self.profile.profile_complete == true
end
end
But cannot seem to figure out what the line in the profile_complete method is. I have got the other bits working in the correct place but cant get this variable across Any help? Cheers :)
def profile_complete?
self.attributes.values.include?(nil) ? false : true
end

Not able to use new model with devise

I have 2 models in my application ( Using rails 3.2.5)
1) User(From devise)
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
end
2) Profiles.
class Profile < ActiveRecord::Base
belongs_to :user
attr_accessible :description, :name, :product, :image, :price
mount_uploader :image, ImageUploader
validates_presence_of :name, :product, :image, :price
end
There are many profiles of one user .
GOAL : I want to display only the profiles related to each user , when they login.
By reading rails document we can create a new profile for a user by (Code below), But this gives an error
"undefined method `Profile' for nil:NilClass"
Can somebody help me to define my controller's index,show,new,edit,create,update ,destroy or show me one and i can do it for all.
def new
#profile = #user.Profile.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #profile }
end
end
You are receiving this error because the #user is not initialized and is equal to nil so it has no method named profile, you should be using current_user helper of devise to get the current user #user = current_user.

retrieve object id from relation in rails3

i have a model
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :meetings, :dependent => :destroy do
def find_foreign
Meeting.where("user_id <> ?", id)
end
end
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me
# attr_accessible :title, :body
end
and when i am trying to get user's foreign meetings like that
some_user.meetings.find_foreign
i get an error
NoMethodError (undefined method `id' for []:ActiveRecord::Relation):
because self in find_foreign is an Array. How to retrive the User.id from this method ?
you can access self here:
def find_foreign
Meeting.where("user_id <> ?", self.id)
end
But don't know why you've written this?
some_user.meetings will already filter meetings by current user id. I've even no idea if block is allowed here!
find_foreign method is in User Model and you are trying to call it on Array of the Object of the Meetings
Just use
some_user.find_foreign

Resources