Add current_user Devise to Mongoid relations - ruby-on-rails

Hi Guys I have a Relationships in Mongoid and I can not add current_user to this relation for get the user that create the deal. A relation with 3 model.
I have three models user.rb, house.rb and deal.rb
user.rb Relationships (devise model)
# Relationships
has_many :houses, dependent: :destroy
has_many :deals, dependent: :destroy
key :title
house.rb
# Relationships
belongs_to :user
embeds_many :deals
deal.rb
# Relationships
embedded_in :house, :inverse_of => :deals
belongs_to :user
In my routes.rb
resources :houses do
resources :deals
end
In my houses_controller.rb in my create method I get current_user for each house of this side:
def create
##house = House.new(params[:house])
#house = current_user.houses.new(params[:house])
respond_to do |format|
if #house.save
format.html { redirect_to #house, notice: 'House was successfully created.' }
format.json { render json: #house, status: :created, location: #house }
else
format.html { render action: "new" }
format.json { render json: #house.errors, status: :unprocessable_entity }
end
end
end
In my deals_controller.rb I have the created method this:
def create
#house = House.find_by_slug(params[:house_id])
#user = User.find(:user_id)
#deal = #house.deals.create!(params[:deal])
redirect_to #house, :notice => "Comment created!"
end
How I can add to this last method create, the current_user that created the deal?

You can simply add these two lines to the create action:
#deal.user=current_user
#deal.save
And I would also suggest you not to use create! instead you should use .new and .save like in the scaffolded create actions! ;)

Related

How to pass id from different table in rails?

Using Devise Gem to store user.
Created One to Many association between User to Project.
Created One to Many Association Between User and Site and Then One to Many Association between Project and Site.
But the error is i am not able to Assign project_id to Site from User Creation form. i am able to Assign from console. here is my code-
sites_controller.rb
def create
#site = current_user.sites.build(site_params)
respond_to do |format|
if #site.save
format.html { redirect_to #site, notice: 'Transactions was successfully Uploaded.' }
format.json { render :show, status: :created, location: #site }
else
format.html { render :new }
format.json { render json: #site.errors, status: :unprocessable_entity }
end
end
end
def site_params
params.require(:site).permit(:name, :amount)
end
site.rb(model)
belongs_to :user
belongs_to :project
User.rb
has_many :projects
has_many :sites
project.rb
has_many :sites, dependent: :destroy
How can i pass project_id on site creation. Is there any other simple way to resolve such problem?
Based on the comments in the question:
# project_id needs to be available to the method,
# in order to be added to site.
#
# Either pass it through params or get it from database
# based on your business logic.
site_params = site_params.merge({project_id: project_id})
#site = current_user.sites.build(site_params)
Should help.
Try permitting the foreign key as well.
def site_params
params.require(:site).permit(:name, :amount, :project_id)
end

How to clean code and eliminate the NoMethodError exception

When a user creates an accounts, the code should allow that user to register a user account through Devise and then create an account, plus a company.
The code should redirect to a wizard setup using the wicked gem.
Users have roles (rolify) and are authorized with Cancancan.
The tables are setup using has_many :through association. This seems to work.
The models are as follows:
user
has_many :accounts_users
has_many :accounts, through: :accounts_users, dependent: :destroy
has_one :company, through: :accounts, dependent: :destroy
users_account
belongs_to :account
belongs_to :user
account
resourcify
has_many :accounts_users
has_many :users, through: :accounts_users, dependent: :destroy
has_one :company
company
belongs_to :account
The create account controller is the following:
def new
#account = Account.new
end
def create
if !current_user.present?
build_resource(sign_in_params)
account = Account.find_or_create_by(org_name: params[:user] [:account])
else
#account = current_user.accounts.create!(account_params)
end
# create a default account and company
#account.save!
current_user.add_role 'owner'
current_account = current_user.accounts.first
# create a company associated with the newly created account
if current_account.companies.empty?
company = current_account.companies.create(company_name: params[:org_name])
else
company = current_account.companies.first
end
resource.update(current_company: company.id)
respond_to do |format|
if #account.save
# redirect to the relevant wizard
format.html { redirect_to after_account_path(:add_account), notice: 'Account was successfully created.' }
else
format.html { render action: 'new' }
format.json { render json: #account.errors, status: :unprocessable_entity }
end
end
end
EDITED VERSION
def create
#account = Account.create(account_params.except(:company))
#account.save!
respond_to do |format|
if #account.save
create_company
format.html { redirect_to #account, notice: 'Account was successfully created.' }
format.json { render :show, status: :created, location: #account }
else
format.html { render :new }
format.json { render json: #account.errors, status: :unprocessable_entity }
end
end
end
def create_company
current_user.add_role 'owner'
current_account = current_user.accounts.first
if current_account.company.nil?
current_account.build_company(company_name: params[:org_name])
#company.save!
else
company = current_account.company
end
resource.update(current_company: company.id)
end
included in Application helper:
def current_account
current_user.accounts.first
end
def current_company
current_user.accounts.first.companies.first
end
it redirects (unexpected) to displaying (show) the Company data right after creation, I receive a nil / no method error.
the index and how controller are:
before_action :set_company, only: [:show, :edit, :update, :destroy,
:new]
def index; end
def show
#company = Company.find_by(id: params[:id])
end
def set_company
#company = current_account.company
end
This seems to work. Editing the Company is a challenge but should get there.
Any advices to get to a better code is welcome
Have you thought about just making the front end handle the case where #name isn't set yet?
<=% #company&.name %>
or
<=% #company.name || "Unknown" %>

How to send a mailer on update of an object in a HABTM join table

I have a User object and an Orgs object that are associated through a HABTM join table. I want to send an email to the users when the Orgs object is updated AND the Org.approved value is set to true. I have an approved boolean on the Org.
I think I've gotten most of the way there but I need help with the step of actually sending the email.
Here's my code
class OrgMailer < ApplicationMailer
default from: 'myemail#example.co'
def org_approved(user, org)
#user = user
#orgs = User.orgs.all
#url = 'http://example.com/login'
mail(to: #user.email, subject: 'Your listing has been approved.')
end
end
User.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
has_and_belongs_to_many :orgs, join_table: :orgs_users
end
Org.rb
class Org < ApplicationRecord
has_and_belongs_to_many :users, join_table: :orgs_users
# after_update :send_approved_listing_email, only: [:update]
attachment :company_image
def send_approved_listing_email
OrgMailer.org_approved(i).deliver_now if org.approved === true
end
end
UPDATED: ADDED ORG_CONTROLLER
I've edited my code to look like the answer below but am now getting a new error: uninitialized constant Org::OrgsUser
It's caused when I hit the #org.users << #user line in the create action.
If I delete this line, I'm able to create an org but it's not associating properly.
org_controller.rb
class OrgsController < ApplicationController
before_action :set_org, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
def index
#orgs = Org.all
#tags = ActsAsTaggableOn::Tag.all
end
def show
end
def new
#org = Org.new
end
def contest
end
def edit
end
def create
#user = current_user
#org = Org.new(org_params)
#org.users << #user
respond_to do |format|
if #org.save
format.html { redirect_to thankyou_path, notice: 'Your listing was successfully created. Our team will approve your listing after review.' }
format.json { render :show, status: :created, location: #org }
else
format.html { render :new }
format.json { render json: #org.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #org.update(org_params)
format.html { redirect_to #org, notice: 'Listing was successfully updated.' }
format.json { render :show, status: :ok, location: #org }
else
format.html { render :edit }
format.json { render json: #org.errors, status: :unprocessable_entity }
end
end
end
def destroy
#org.destroy
respond_to do |format|
format.html { redirect_to orgs_url, notice: 'Listing was successfully destroyed.' }
format.json { head :no_content }
end
end
def tagged
if params[:tag].present?
#orgs = Org.tagged_with(params[:tag])
else
#orgs = Org.postall
end
end
private
def set_org
#org = Org.find(params[:id])
end
def org_params
params.require(:org).permit(:twitter, :linkedin, :facebook, :name, :offer, :offercode, :url, :descrption, :category, :approved, :company_image, :tag_list => [])
end
end
I'm using active admin for my admin panel and have a batch action to update any selected orgs and approve them. I think what I'm missing is that in the send_approved_listing_email method I need to iterate through the orgs and email each user when the org is approved.
Right now nothing happens on update so I'm sure I'm not doing this correctly. What am I missing? How should I write this?
I would create a model for the join table rather than using habtm. That way you can use a callback when the join object is saved:
class User < ApplicationRecord
has_many :orgs_users
has_many :orgs, through: :orgs_users
end
class Org < ApplicationRecord
has_many :orgs_users
has_many :users, through: :orgs_users
end
class OrgsUsers < ApplicationRecord
belongs_to :org
belongs_to :user
after_create :send_approved_listing_email
def send_approved_listing_email
OrgMailer.org_approved(user, org).deliver_now if org.approved === true
end
end

Uninitialized constant error using a relationship

I followed the instructions here to create a model Lesson in which there is a student and a teacher (both of the model User) and also a lesson start date.
#Lesson Controller
class Lesson < ActiveRecord::Base
belongs_to :student, class_name => 'User'
belongs_to :teacher, class_name => 'User'
end
#User Controller
class User < ActiveRecord::Base
has_many :lessons_to_attend, :class_name => 'Lesson', :foreign_key => 'student_id'
has_many :lessons_to_teach, :class_name => 'Lesson', :foreign_key => 'teacher_id'
end
The migration went smoothly and so on a page I try to query the student's lessons for tomorrow:
<% #date = 1.day.from_now %>
<%= #date.strftime("%A")%></br>
<%= #date.strftime("%-d/%-m/%y")%>
<% #user.lessons_to_attend.each do |l| %>
Lesson
<% end %>
But when I navigate to this page I get the error Uninitialized constant error Lesson::User
What did I miss out? I'll include the User controller in case something needs to be added in there.
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
# GET /users
# GET /users.json
def index
#users = User.all
end
# GET /users/1
# GET /users/1.json
def show
#user = User.find(params[:id])
end
# GET /users/new
def new
#user = User.new
end
# GET /users/1/edit
def edit
end
# POST /users
# POST /users.json
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: 'User was successfully created.' }
format.json { render :show, status: :created, location: #user }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /users/1
# PATCH/PUT /users/1.json
def update
respond_to do |format|
if #user.update(user_params)
format.html { redirect_to #user, notice: 'User was successfully updated.' }
format.json { render :show, status: :ok, location: #user }
else
format.html { render :edit }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# DELETE /users/1
# DELETE /users/1.json
def destroy
#user.destroy
respond_to do |format|
format.html { redirect_to users_url, notice: 'User was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_user
#user = User.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def user_params
params[:user]
end
end
Two things:
belongs_to :student, class_name => 'User'
belongs_to :teacher, class_name => 'User'
Syntax error on class_name. That should either be :class_name => 'User' or class_name: 'User'.
The other thing is that I think you need to set your inverse_of on both sides of the association.
class Lesson < ActiveRecord::Base
belongs_to :student, class_name: 'User', inverse_of: :lessons_to_attend
belongs_to :teacher, class_name: 'User', inverse_of: :lessons_to_teach
end
class User < ActiveRecord::Base
has_many :lessons_to_attend, class_name: 'Lesson', foreign_key: 'student_id', inverse_of: :student
has_many :lessons_to_teach, class_name: 'Lesson', foreign_key: 'teacher_id', inverse_of: :teacher
end

NameError with a Many to Many association

I'm trying to add a Join/Unjoin button to user created Events, similar to a Follow/Unfollow button for Users.
I'm not sure what to define #rsvps as in the event#show
NameError in Events#show
undefined local variable or method `event' for #<#:0x007f9dfaf9d978>
show.html.erb
<%= link_to "Join Event", rsvps_path(:event_id => event), :method => :post %>
events_controller.rb
def show
#event = Event.find(params[:id])
#user = current_user
##rsvp = ???? something here ????
end
rsvps_controller.rb
class RsvpsController < ApplicationController
before_filter :signed_in_user
def create
#rsvp = current_user.rsvps.build(:event_id => params[:event_id])
if #rsvp.save
flash[:notice] = "Joined event."
redirect_to root_url
else
flash[:error] = "Unable to join event."
redirect_to root_url
end
end
def destroy
#rsvp = current_user.rsvps.find(params[:id])
#rsvp.destroy
flash[:notice] = "Unjoin Event."
redirect_to current_user
end
end
Here are the models
rsvp.rb
class Rsvp < ActiveRecord::Base
attr_accessible :event_id, :user_id
belongs_to :user
belongs_to :event
end
user.rb
has_many :rsvps
has_many :events, through: :rsvps, dependent: :destroy
event.rb
belongs_to :user
has_many :rsvps
has_many :users, through: :rsvps, dependent: :destroy
Your undefined local variable or method error seems to be coming from trying to pass :event_id => event to your controller through rsvp_path. Instead you should just be passing the event object like so
<%= link_to "Join Event", rsvps_path(event), :method => :post %>
the line #event = Event.find(params[:id]) in your controller will take care of figuring out what event you passed to it.
I think this code would be more rails-ish.
# user.rb
has_many :users_events
has_many :events, through: :users_events
# event.rb
has_many :users_events
has_many :users, through: :users_events
# users_event.rb
belongs_to :user
belongs_to :event
ActiveRecord do everything else. 8)
For example user.events and event.users methods.
Join and unjoin to user actions may be processed by events controller. Update method can look like this
# events_controller.rb
def update
respond_to do |format|
#event = Event.find(params[:id])
#event.users << current_user if params[:action] == 'join'
#event.users.delete(current_user) if params[:action] == 'unjoin'
if #event.update_attributes(params[:event])
format.html { redirect_to #event, notice: 'Event was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #event.errors, status: :unprocessable_entity }
end
end
end
A little bit messy, but I hope the idea is clear.

Resources