I have a one-to-one relationship between a User and a Partner. In my User model, I have the following:
has_one :partner, :class_name => "Partner"
I want to create a new Partner if "relation_status == coupled" and then make the user go to a new form to fill out information on his/her Partner. So in my UsersController, I have
respond_to do |format|
if #user.save && #user.relation_status != "Coupled"
format .html { redirect_to #user, notice: "User was successfully created ID
was #{#id} "}
format.json { render json: #user, status: :created, location: #user }
elsif #user.save && #user.relation_status == "Coupled"
format .html { redirect_to partner_signup_path, notice: "Time for your patna"
}
format.json { render json: #user, status: :created, location: #user }
else
format.html { render action: "new" }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
In my PartnersController, I have the basic new and create actions that successfully create a new Partner. Obviously, there's no way to have the Partner's ID assigned to the User's foreign key - partner_id automatically by doing what I did above. How can I go about doing this correctly? Should I be doing this in the User model instead? I'm kind of a Rails newbie. Thanks for the help.
The answer is to keep the user in session in the UsersController -> session[:id] = #user.id .
Then in the PartnersController, I did:
#partner = Partner.new(params[:user])
#partner.save
#user = User.find(session[:id])
#user.partner = #partner
Voila.
Related
I have following table in database and also the model created for it.
|id |name |description |created_date |updated_date |
-----------------------------------------------------------------------
|1 |HELLO |greeting |2017-09-28 18:51:51 |2017-09-28 18:51:51|
model.rb
class Person < ApplicationRecord
has_many :person_activities
validates :name, uniqueness: true
end
I want to create update action in controller. It will update the name and description based on the name passed. e.g i want to update the name HELLO to HI. How can i create update action for that?
I tried following update action in controller but it wont hit the update action
def update
byebug
redirect_to Person.find(name: params[:id]).tap { |person|
person.update!(person_params)
}
end
private
def person_params
params.require(:person).permit(:name)
end
routes.rb
resources :person, only: [:index, :show, :create, :update, :destroy], defaults: { format: :json }
Tried testing like this http://localhost:1111/person/HELLO and passing { name: 'HI'} in body params. I am using postman for testing.
You can modify your model, something like this:
class Person< ActiveRecord::Base
before_save :change_name
private
def change_name
self.name="HI" if self.name=="HELLO"
end
end
To answer this properly we would need to understand the logic of how creating a new record with name = "HELLO" would need to be set to "HI". Do you have a lookup table for this logic or is it hardcoded?
The easiest thing I could think of is you can change the value of the passed parameter before doing the update by setting the value of the parameter. E.G.
params["name"] = "HI"
So when you do a person.update it will use the "name" param set to "HI".
Then you could do this in a
def update
respond_to do |format|
params["name"] = "HI"
if #person.update(person_params)
format.html { redirect_to #person, notice: 'Person was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #person.errors, status: :unprocessable_entity }
end
end
end
You could also do the update then just set the value after the update:
def update
respond_to do |format|
if #person.update(person_params)
#person.name = "HI"
#person.save
format.html { redirect_to #person, notice: 'Person was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #person.errors, status: :unprocessable_entity }
end
end
end
From postman you need to call login action first. So it will create a session in postman and then you can call update action.
I am developing application using stripe for payment. I have Plan and Subscription model in my app. Plan has many subscriptions and subscription belongs t plan. On plans index page i have plans listings and user can click on any of the plans
<td><%=link_to plan.name, new_subscription_path(:plan_id => plan.id) %></td>
and in my subscription controller i have this
def new
#plan = Plan.find(params[:plan_id])
#subscription = #plan.subscriptions.new
end
def create
#plan = Plan.find(params[:plan_id])
#subscription = #plan.subscriptions.new(subscription_params)
respond_to do |format|
if #subscription.save
format.html { redirect_to #subscription, notice: 'Subscription was successfully created.' }
format.json { render :show, status: :created, location: #subscription }
else
format.html { render :new }
format.json { render json: #subscription.errors, status: :unprocessable_entity }
end
end
end
I am trying to build subscription on particular plan but i am getting this error
Couldn't find Plan with 'id'=
You should update your config/routes.rb to look like:
resources :plans do
resources :subscriptions
end
And later in your template, you should use new_plan_subscription_path like:
<td><%=link_to plan.name, new_plan_subscription_path(:plan_id => plan.id) %></td>
This should help!
Good luck!
Before I begin, let me say that I have two different devise user models.
I began removing the unnecessary methods from the scaffold_controller, because devise handles certain actions.
I'm trying to route to the current_user profile page, but I get an error every time I try to add the link in my navbar <%= 'My Profile', current_user %> doesn't work in this case. I plan to setup the associations as soon as I finish hooking up these controllers.
class ProfilesController < ApplicationController
before_action :set_profile, only: [:show, :edit, :update, :destroy]
# GET /profiles
# GET /profiles.json
def index
#profiles = Profile.all
end
# GET /profiles/1
# GET /profiles/1.json
def show
#user = User.find(params[:id])
respond_to do |format|
format.html
format.json {render :json => #user }
end
end
# GET /profiles/1/edit
def edit
end
# PATCH/PUT /profiles/1
# PATCH/PUT /profiles/1.json
def update
respond_to do |format|
if #profile.update(profile_params)
format.html { redirect_to #profile, notice: 'Profile was successfully updated.' }
format.json { render :show, status: :ok, location: #profile }
else
format.html { render :edit }
format.json { render json: #profile.errors, status: :unprocessable_entity }
end
end
end
# DELETE /profiles/1
# DELETE /profiles/1.json
def destroy
#profile.destroy
respond_to do |format|
format.html { redirect_to profiles_url, notice: 'Profile was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_profile
#profile = Profile.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def profile_params
params[:profile]
end
end
profiles GET /profiles(.:format) profiles#index
POST /profiles(.:format) profiles#create
new_profile GET /profiles/new(.:format) profiles#new
edit_profile GET /profiles/:id/edit(.:format) profiles#edit
profile GET /profiles/:id(.:format) profiles#show
PATCH /profiles/:id(.:format) profiles#update
PUT /profiles/:id(.:format) profiles#update
DELETE /profiles/:id(.:format) profiles#destroy
Assuming (such as bad thing to do), that you have already created the profile while creating the user ( since there is no create action in the controller ) and that a profile belongs_to a user, then this should work:
<%= link_to "My Profile", current_user.profile %>
Generally, I would get my associations set up properly before I even look at the controllers.
I am new to rails and working on a rails application.
I have installed the Devise gem and find it helpful in many areas, however I cannot create a new user unless I do it on the Rails Console. I find this especially frustrating. Does anyone have any suggestions or solutions?
When I sign up as an employee I get the following error "CanCan::AccessDenied in JobsController#index"
Also please note that when I verified my user model in devise and I have already included "include Devise::Models::DatabaseAuthenticatable"
My jobs_controller.rb file
def index
#users = User.all
#user = current_user
#jobs = Job.all
#jobs = Job.paginate(:page => params[:page], :per_page => 3)
end
# GET /jobs/1
# GET /jobs/1.json
def show
end
# GET /jobs/new
def new
#job = Job.new(:date => Time.now, :date_of_loss => Time.now, :sign_date => Time.now, :time_called_in => Time.now)
end
# GET /jobs/1/edit
def edit
end
# POST /jobs
# POST /jobs.json
def create
#job = Job.new(job_params)
respond_to do |format|
if #job.save
format.html { redirect_to #job, notice: 'Job was successfully created.' }
format.json { render action: 'show', status: :created, location: #job }
else
format.html { render action: 'new' }
format.json { render json: #job.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /jobs/1
# PATCH/PUT /jobs/1.json
def update
respond_to do |format|
if #job.update(job_params)
format.html { redirect_to #job, notice: 'Job was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #job.errors, status: :unprocessable_entity }
end
end
end
# DELETE /jobs/1
# DELETE /jobs/1.json
def destroy
#job.destroy
respond_to do |format|
format.html { redirect_to jobs_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_job
#job = Job.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def job_params
params.require(:job).permit(:date, :time_called_in, :date_of_loss, :contact, :job_address, :city, :postal_code, :site_phone, :work_phone, :cell_phone, :email, :referred_by, :insurance_company, :policy_number, :claim_number, :broker, :insurance_address, :insurance_city, :insurance_province, :insurance_postal_code, :insurance_phone, :insurance_contact, :insurance_email, :customer_name, :customer_address, :authorized, :signed_by_name, :sign_date, :signature, :contact_first_name, :contact_last_name)
end
end
My ability model looks like this
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.role == "admin"
can :manage, :all
elsif user.role == "manager"
can [:read, :update, :create], [Job, Equipment]
#can [:read, :update, :create], [Equipment]
elsif user.role == "employee"
can [:read, :update, :create], [Equipment, Job]
cannot [:create], [Job]
#can [:read, :update], [Equipment]
end
end
If you are getting this error: CanCan::AccessDenied in JobsController#index it's because your user is not authorized to access the JobsController#index method and has nothing to do with creating users.
Can you explain what you mean when you say you "Sign up as an employee"? Do you have a roles table or a boolean on the users table to indicate that a user is an employee?
Please post your Ability.rb class (possibly in app/models/ability.rb) as that's where the access controls for cancan are defined.
Try changing this:
user ||= User.new # guest user (not logged in)
to this:
user ||= User.new # guest user (not logged in)
puts "user.role = #{user.role}"
and then check your logs to see what the value of user.role is. I'm wondering if your user does not have the role that you think it does.
I wrote the following migration:
class AddValidationsToAnimals < ActiveRecord::Migration
def change
add_index :animals, [:name, :user_id], :unique => true
end
end
Ok. Then, in my model, I add the following validation:
validates_uniqueness_of :name, :scope => :user_id
When I try to add a registry that will hurt this rule, unless get a pretty message in my view, I got a RecordNotUnique Exception.
Why? How can I fix that?
Thanks in advance.
def create
#animal = current_user.animals.new(params[:animal])
#animal.valid?
respond_to do |format|
if #animal.save
format.html { redirect_to #animal, notice: 'Animal registrado com sucesso.' }
format.json { render json: #animal, status: :created, location: #animal }
else
format.html { render action: "new" }
format.json { render json: #animal.errors, status: :unprocessable_entity }
end
end
end
Please paste your method code here. Is it a common object.save? Try to call object.valid? before and check if it's returning false.