Render view another controller - ruby-on-rails

i have a noob problem. I need render view from another controller. I use devise and create a perfil controller.
Perfil Controller:
class PerfilController < ApplicationController
before_filter :authenticate_user!
def index
end
def show
#usuario = User.find(current_user)
#usuario.perfil ||= #usuario.build_perfil
#perfil = #usuario.perfil
end
def update
#usuario = User.find(current_user)
#perfil = Perfil.new(perfil_params)
#usuario.perfil ||= #usuario.build_perfil
respond_to do |format|
if #usuario.perfil.update_attributes(perfil_params)
format.html {redirect_to #usuario, notice: "update" }
else
format.html { render action: "show"}
end
end
end
private
def perfil_params
params.require(:perfil).permit(:nombre, :apellido)
end
end
User controller:
class UsersController < ApplicationController
before_filter :authenticate_user!
after_action :verify_authorized
def index
#users = User.all
authorize User
end
def show
#user = User.find(params[:id])
authorize #user
end
def update
#user = User.find(params[:id])
authorize #user
if #user.update_attributes(secure_params)
redirect_to users_path, :notice => "User updated."
else
redirect_to users_path, :alert => "Unable to update user."
end
end
def destroy
user = User.find(params[:id])
authorize user
user.destroy
redirect_to users_path, :notice => "User deleted."
end
private
def secure_params
params.require(:user).permit(:role)
end
end
class PerfilController < ApplicationController
before_filter :authenticate_user!
def index
end
def show
#usuario = User.find(current_user)
#usuario.perfil ||= #usuario.build_perfil
#perfil = #usuario.perfil
end
def update
#usuario = User.find(current_user)
#perfil = Perfil.new(perfil_params)
#usuario.perfil ||= #usuario.build_perfil
respond_to do |format|
if #usuario.perfil.update_attributes(perfil_params)
format.html {redirect_to #usuario, notice: "actualizado" }
else
format.html { render action: "show"}
end
end
end
private
def perfil_params
params.require(:perfil).permit(:nombre, :apellido)
end
end
Perfil/show
<h2>Edit </h2>
<%= form_for #perfil, :url=>{:action=>:update}, :html=>{:method=>:put} do |f| %>
<p><%= f.label :nombres %><br />
<%= f.text_field :nombre %></p>
<div><%= f.label :apellidos %><br />
<%= f.text_field :apellido %></div>
<div><%= f.submit "Actualizar" %></div>
<% end %>
<%= link_to "AtrĂ¡s", :back %>
well, i need show update in users/index
<h3>Configuracion de la cuenta</h3>
<div class = "col-md-3"> <h3>Users</h3>
<div class="nav nav-pills nav-stacked">
<%= render 'users/menu' %>
</div>
</div>
<div class = "col-md-7">
<h3>Informacion</h3>
<%= render 'users/show' %>
</div>
I hope I explained well.
Regards.

You can render any view from your application..using render
take care of the variables used inside the view and do include them in the method call.
RENDER ONLY RENDERS THE VIEW AND DO NOT CALLS THE ACTION OF THE CONTROLLER
render other controller view from the controller..
in users_controller.rb
##render partial from views/profile
respond_to do |format|
format.js { render 'profile/upload' }
format.html 'profile/upload'
end
same can be used in view file as well
<%= render 'profile/upload'%>

Related

Rails has_one Association (user,company)

class User < ActiveRecord::Base
has_one :comapny
end
class Comapny < ApplicationRecord
belongs_to :user
end
Hi! i created rails association mentioned above. I want user to create only one company (for example: User with id(1) should only make 1 company only).
But even with has_one i am able to make more then 1 company for user1.
can anyone help?
user_controller.rb
class UsersController < ApplicationController
before_action :set_user, only: [:edit, :update, :show]
before_action :require_user, only: [:index, :show, :update ]
before_action :require_same_user, only: [:edit, :destroy, :update]
before_action :require_admin, only: [:destroy]
def index
#user = User.all
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
session[:user_id] = #user.id
flash[:success] = "Welcome #{#user.username}"
redirect_to user_path(#user)
else
render 'new'
end
end
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update(user_params)
flash[:success] = "Account was updated"
else
render 'new'
end
end
def show
end
def destroy
#user = User.find(params[:id])
#user.destroy
flash[:danger] = "User is destroyed"
redirect_to root_path
end
private
def user_params
params.require(:user).permit(:username, :email, :password, :role, :first_name, :last_name)
end
def set_user
#user = User.find(params[:id])
end
def require_same_user
if current_user != #user and !current_user.admin?
flash[:danger] = "Not authorized"
redirect_to user_path
end
end
def require_admin
if logged_in? and !current_user.admin?
flash[:danger] = "Not authorized"
redirect_to user_path
end
end
end
**comapny_controller.rb**
class ComapniesController < ApplicationController
before_action :set_comapny, only: %i[ show edit update destroy ]
before_action :require_user, only: [:create]
# GET /comapnies or /comapnies.json
def index
#comapnies = Comapny.all
end
# GET /comapnies/1 or /comapnies/1.json
def show
end
# GET /comapnies/new
def new
#comapny = Comapny.new
end
# GET /comapnies/1/edit
def edit
end
# POST /comapnies or /comapnies.json
def create
#comapny = Comapny.new(comapny_params)
respond_to do |format|
if #comapny.save
format.html { redirect_to comapny_url(#comapny), notice: "Comapny was successfully created." }
format.json { render :show, status: :created, location: #comapny }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: #comapny.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /comapnies/1 or /comapnies/1.json
def update
respond_to do |format|
if #comapny.update(comapny_params)
format.html { redirect_to comapny_url(#comapny), notice: "Comapny was successfully updated." }
format.json { render :show, status: :ok, location: #comapny }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: #comapny.errors, status: :unprocessable_entity }
end
end
end
# DELETE /comapnies/1 or /comapnies/1.json
def destroy
#comapny.destroy
respond_to do |format|
format.html { redirect_to comapnies_url, notice: "Comapny was successfully destroyed." }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_comapny
#comapny = Comapny.find(params[:id])
end
# Only allow a list of trusted parameters through.
def comapny_params
params.require(:comapny).permit(:name, :year_founded, :user_id)
end
end
**Coampny_form.html.erb**
<%= form_with(model: comapny, local: true) do |form| %>
<% if comapny.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(comapny.errors.count, "error") %> prohibited this comapny from being saved:</h2>
<ul>
<% comapny.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :name %>
<%= form.text_field :name, id: :comapny_name %>
</div>
<div class="field">
<%= form.label :year_founded %>
<%= form.date_select :year_founded, id: :comapny_year_founded %>
</div>
<div class="field">
<%= form.label :user_id %>
<%= form.text_field :user_id, id: :comapny_user_id, value: current_user.id %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
I made a typo while generating scaffold of coapmny instead of company. ignore that
Add a uniqueness constraint to the db table and a uniqueness validation to the company model:
class Comapny < ApplicationRecord
belongs_to :user
validates :user_id, uniqueness: true
end

No route matches {:action=>"new", :controller=>"profiles", :id=>"address"}, missing required keys: [:user_id]

I work with Device and just added the 'wicked' gem to my Rails app. In my RegistrationsController I have defined the following:
class Users::RegistrationsController < Devise::RegistrationsController
def new
super
end
def create
super
end
def update
super
end
protected
def after_sign_up_path_for(resource)
user_steps_path
end
def after_update_path_for(resource)
new_user_profile_path(current_user.id)
end
end
Basically I wish my form to have one further step after sign up, which would be the address:
class UserStepsController < ApplicationController
include Wicked::Wizard
steps :address
def show
#user = current_user
render_wizard
end
end
After the User has given his address, I want him/her to be redirected to their profile, where they can also give the information about themselves. My thinking, this is an update action in my RegistrationsController. Or how do I redirect to the profile, after my multistep form is finilised, meaning the step address is done? Here is address.html.erb:
<%= form_for #user, url: wizard_path do |f| %>
<div class="field">
<%= f.label :street %>
<%= f.text_area :street %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
For now ActionContoller complains about my header routes and looks for id address and I don't get why... Here is my ProfilesContorller:
class ProfilesController < ApplicationController
before_action :set_profile, only: [:show, :edit, :update, :destroy]
def show
#user = User.eager_load(:profile).find(params[:user_id])
#profile = #user.profile
#review = Review.new
#reviews = Review.where(profile: #profile)
end
def new
#user = current_user
#profile = Profile.new
end
def edit
#profile = #user.profile
end
def create
#user = current_user
#profile = #user.build_profile(profile_params)
respond_to do |format|
if #profile.save
format.html { redirect_to user_profile_path(current_user.id), notice: 'Profile was successfully created.' }
format.json { render :show, status: :created, location: #profile }
else
format.html { render :new, notice: 'Did not save' }
format.json { render json: #profile.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #profile.update(profile_params)
format.html { redirect_to user_profile_path(current_user.id), 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
def destroy
#profile.destroy
respond_to do |format|
format.html { redirect_to users_url, notice: 'Profile was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_profile
#profile = current_user.profile
end
def profile_params
params.permit(:about, :avatar)
end
end
And here is the error part in my header.html.erb
<% if current_user.profile == nil %>
<li><span class="bg-primary text-white rounded"><%= link_to 'Create profile', new_user_profile_path%></span></li>
<% else %>
<li><span class="bg-primary text-white rounded"><%= link_to 'My profile', user_profile_path(#user) %></span></li>
<% end %>
<li><span class="bg-primary text-white rounded"><%= link_to 'Log out', destroy_user_session_path, method: :delete %></span></li>
ActionController basically complains about the second line and the "new_user_profile_path". How did address got into profiles contoller -> new -> id and how do I procees with the error mentioned in the title. Thank you!
As per your Error, user_id is missing in your route
Try, new_user_profile_path(#user) in second line
So finally it should be <%= link_to 'Create profile', new_user_profile_path(#user)%>

Update child attributes rails

I have a customer model and book_room model
class Customer < ApplicationRecord
has_many :book_rooms
accepts_nested_attributes_for :book_rooms
end
class BookRoom < ApplicationRecord
belongs_to :customer
end
in the book_room controller the create method is from its parent
class BookRoomsController < ApplicationController
def create
#customer = Customer.find(params[:customer_id])
#customer_room = #customer.book_rooms.create(book_rooms_params)
flash[:notice] = "Customer has been added to room"
redirect_to customer_path(#customer)
end
def destroy
#customer = Customer.find(params[:customer_id])
#customer_room = #customer.book_rooms.find(params[:id])
#customer_room.destroy
flash[:notice] = "Customer room has been deleted"
redirect_to customer_path(#customer)
end
def edit
#customer = Customer.find(params[:customer_id])
end
def update
#customer = Customer.find(params[:customer_id])
#customer.book_rooms.update(book_rooms_params)
flash[:notice] = "Customer has checked out"
redirect_to #customer
end
private
def book_rooms_params
params.require(:book_room).permit(:room, :first_name, :last_name, :phone_number, :checked_out)
end
end
in the Customer show page
<%= form_for [#customer, #customer.book_rooms.build] do |f| %>
<% #room = Room.all %>
<%= f.label "Room: "%>
<%= f.select(:room, #room.collect { |a| [a.room_number, a.id] }) %>
<%= f.submit "Enter" %>
<div class="col-md-12"><%= render #customer.book_rooms.order("created_at DESC") %></div>
This works perfectly and all child objects get created. now when I try to edit the child attributes it doesn't update at all
heres the edit form in the book_room edit page/action
<%= form_for #customer do |f| %>
<%= f.fields_for :book_rooms, #customer.book_rooms do |f| %>
<%= f.check_box :checked_out %>
<% end %>
<%= f.submit "Enter" %>
is there something i am doing wrong? why doesn't it update?
Customers controller
class CustomersController < ApplicationController
before_action :set_customer, only: [:show, :edit, :update, :destroy]
# POST /customers.json
def create
#customer = Customer.new(customer_params)
respond_to do |format|
if #customer.save
format.html { redirect_to #customer, notice: 'Customer was successfully created.' }
format.json { render :show, status: :created, location: #customer }
else
format.html { render :new }
format.json { render json: #customer.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #customer.update(customer_params)
format.html { redirect_to #customer, notice: 'Customer was successfully updated.' }
format.json { render :show, status: :ok, location: #customer }
else
format.html { render :edit }
format.json { render json: #customer.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_customer
#customer = Customer.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def customer_params
params.require(:customer).permit(:first_name, :last_name, :phone_number, :sex, :book_rooms_attributes => [:checked_out])
end
In your customers controller :
Try to change your function customer_params like:
def customer_params
params.require(:customer).permit(:first_name, :last_name, :phone_number, :sex, {:book_rooms => [:checked_out]})
end
For more explications see here
Change your update method to:
def update
#customer = Customer.find(params[:customer_id])
if #customer.update_attributes(customer_params)
flash[:notice] = "Customer has checked out"
redirect_to #customer
else
...redirect to edit page with a flash error message ...
end
end
You also need to modify your edit page.
<%= form_for(:customer, :url => {:action => 'update', :id => #customer.id}, :method => 'PUT') do |f| %>
Try changing the URL to update and changing the method to patch you will go to update method.
<%= form_for :customer, url: customer_path(#customer),method: :patch do |f| %>
<%= f.fields_for :book_rooms, #customer.book_rooms do |f| %>
<%= f.check_box :checked_out %>
<% end %>
<%= f.submit "Enter" %>

Unknown Action: The action 'create' could not be found for CommentsController

I'm working on an app that allows users to comment on a single "work" (think blog post). The associations in the models are as follows:
class User < ActiveRecord::Base
has_many :works
has_many :comments
class Work < ActiveRecord::Base
belongs_to :user
has_many :comments
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :post
belongs_to :work
There's a form on the Works show page that allows users to post a comment:
<%= form_for(#comment) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_area :content, placeholder: "Post a comment!" %>
</div>
<%= f.submit "Post", class: "btn btn-small btn-primary" %>
<% end %>
The Works controller is as follows. Note that I'm adding the build comment functionality here so that the form on the Works page functions:
class WorksController < ApplicationController
#before_filter :current_user, only: [:edit, :update]
def index
#works = Work.all
#comment = #work.comments.build(params[:comment])
#comment.user = current_user
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #works }
end
end
def create
#work = current_user.works.create(params[:work])
redirect_to current_user
end
def edit
#work = current_user.works.find(params[:id])
end
def new
#work = current_user.works.new
end
def destroy
#work = current_user.works.find(params[:id]).destroy
flash[:success] = "Work deleted"
redirect_to current_user
end
def update
#work = current_user.works.find(params[:id])
if #work.update_attributes(params[:work])
flash[:success] = "Profile updated"
redirect_to #work
else
render 'edit'
end
end
def show
#work = Work.find(params[:id])
#comment = #work.comments.build
#comment.user = current_user
#activities = PublicActivity::Activity.order("created_at DESC").where(trackable_type: "Work", trackable_id: #work).all
#comments = #work.comments.order("created_at DESC").where(work_id: #work ).all
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #work }
end
end
end
And lastly, here is the Comments controller:
class CommentsController < ApplicationController
before_filter :authenticate_user!
def index
#comments = Comment.all
end
def show
#comment = Comment.find(params[:id])
#activities = PublicActivity::Activity.order("created_at DESC").where(trackable_type: "Comment", trackable_id: #comment).all
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #comment }
end
def update
#comment = current_user.comments.find(params[:id])
if #comment.update_attributes(params[:comment])
flash[:success] = "Comment updated"
redirect_to #comment
end
end
def create
#work = Work.find(params[:id])
#comment = #work.comments.build(params[:comment])
#comment.user = current_user
if #comment.save
#flash[:success] = "Post created!"
redirect_to #work
else
render 'home#index'
end
end
end
end
When I attempt to submit a comment using the comment form on the works show view page, I get the following error:
Unknown action
The action 'create' could not be found for CommentsController
Why can't it find the create action on the Comments controller? Any help would be greatly appreciated.
Thanks!
Your comments controller show action is missing an end, i.e. this:
def show
#comment = Comment.find(params[:id])
#activities = PublicActivity::Activity.order("created_at DESC").where(trackable_type: "Comment", trackable_id: #comment).all
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #comment }
end
should be this:
def show
#comment = Comment.find(params[:id])
#activities = PublicActivity::Activity.order("created_at DESC").where(trackable_type: "Comment", trackable_id: #comment).all
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #comment }
end
end
(right now it is 'falling' into the create action so the create action never gets set up).
You will then probably need to change the final:
end
end
end
end
to be
end
end
end
as this was probably 'compensating' for the mismatch and allowing the page to precompile in Ruby.

Creating an AJAX Form for a Polymorphic Object in Rails

I am trying to create an AJAX form for a polymorphic associated model.
I created "Comments" which have a polymorphic association with all objects you can comment on (i.e. user profiles, organization profiles, events, etc).
I can currently add comments to objects using a form created by:
form_for [#commentable, #comment] do |f|
I am trying to make this form via Ajax but I keep getting errors.
I've tried at least ten different pieces of code, using remote_form_tag, remote_form_for, etc..with all different options, and nothing works. The comment does not get inserted into the database.
Specifically, I tried:
<% remote_form_for(:comment, :url => comments_path(#profile)) do |f| -%>
In my routes.rb, profile has many comments. And comments belongs to Profile. But when I submit the form nothing happens and the comment does not get posted to the database.
Can anyone please tell me what I'm doing wrong?
For your reference, here are my controllers. Comments controller:
class CommentsController < ApplicationController
layout 'index'
def index
#commentable = find_commentable
#comments = #commentable.comments
end
def show
#comment = Comment.find(params[:id])
end
def new
#comment = Comment.new
end
def create
#commentable = find_commentable
#comment = #commentable.comments.build(params[:comment])
#comment.user_id = current_user.id
if #comment.save
responsetext = "<p><b>Comment: </b>" + #comment.content + "</p>"
render :text => responsetext
else
responsetext = "error"
render :text => responsetext
end
end
def edit
#comment = Comment.find(params[:id])
end
def update
#comment = Comment.find(params[:id])
if #comment.update_attributes(params[:comment])
flash[:notice] = "Successfully updated comment."
redirect_to #comment
else
render :action => 'edit'
end
end
def destroy
#comment = Comment.find(params[:id])
#comment.destroy
flash[:notice] = "Successfully destroyed comment."
redirect_to comments_url
end
private
def find_commentable
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
nil
end
end
Profile controller:
class ProfilesController < ApplicationController
# GET /profiles
# GET /profiles.xml
layout 'index'
def index
##profile = Profile.find_by_user_id(current_user.id)
#profile = current_user.profile
#comment = Comment.new
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #profile }
end
end
# GET /profiles/1
# GET /profiles/1.xml
def show
#profile = Profile.find(params[:id])
#commentable = #profile
#comment = Comment.new(:commentable => #profile)
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #profile }
end
end
# GET /profiles/new
# GET /profiles/new.xml
def new
#profile = Profile.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #profile }
end
end
# GET /profiles/1/edit
def edit
##profile = Profile.find(params[:id])
#profile = current_user.profile
end
# POST /profiles
# POST /profiles.xml
def create
#profile = Profile.new(params[:profile])
respond_to do |format|
if #profile.save
flash[:notice] = 'Profile was successfully created.'
format.html { redirect_to(#profile) }
format.xml { render :xml => #profile, :status => :created, :location => #profile }
else
format.html { render :action => "new" }
format.xml { render :xml => #profile.errors, :status => :unprocessable_entity }
end
end
end
# PUT /profiles/1
# PUT /profiles/1.xml
def update
#profile = Profile.find(params[:id])
respond_to do |format|
if #profile.update_attributes(params[:profile])
flash[:notice] = 'Profile was successfully updated.'
format.html { redirect_to(#profile) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #profile.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /profiles/1
# DELETE /profiles/1.xml
def destroy
#profile = Profile.find(params[:id])
#profile.destroy
respond_to do |format|
format.html { redirect_to(profiles_url) }
format.xml { head :ok }
end
end
end
View:
<% remote_form_for([#commentable,#comment], :url => '/profiles/1/comments') do |f| -%>
<% #form_for [#commentable, #comment] do |f| %>
<br />
<%= f.text_area :content %><br />
<%= submit_tag 'Post', :disable_with => 'Please wait...' %>
<% end %>
<h2>Comments</h2>
<div id="comments">
<% #profile.comments.each do |c| %>
<div>
<div style="float:left;width:50px">
<%= image_tag c.user.profile.photo.url(:thumb) %>
</div>
<div style="float:left;padding:5px">
<b><%= link_to c.user.name, profile_path(c.user.profile) %></b>
<%=h c.content %><br />
<font style="color:grey"><%=h distance_of_time_in_words(Time.at(c.created_at.to_i).to_i,Time.now.to_i, include_seconds = true) %> ago</font>
</div>
</div>
<div style="clear:both"></div>
<% end %>
</div>
Could you paste the controller code? You need to have accepts_nested_attributes_for :comments in your profile model. In your controller you need to have
profile[:comments_attributes] = params[:comment]
profile.save

Resources