How to Edit and Update using Faraday Call in Rails - ruby-on-rails

I tried to edit and update columns using Faraday Call on my rails app, I am successfully updating the columns by adding new value.
But I want during update, initially in edit_form, it must show my old values where i can edit it, and then update.
This is my Connection Request
def connection
Faraday.new(url: ENV['URL'],
params: { clientId: ENV['CLIENT_ID'] },
headers: { 'Authorization' => oauth_token_generation })
end
This is my edit_request to call end point for connection and update
def edit_request(type,id, params)
response = connection.patch("#{type}/#{id}", params)
JSON.parse(response.body)
rescue JSON::ParserError
Rails.logger.error 'Invalid Json Data'
nil
rescue Faraday::Error => e
Rails.logger.error "Connection Failed #{e}"
nil
end
This is my calling method:
def self.get_entities(id,params)
response = Api::Connection.edit_request('entities',id, params)
end
My Controller:
def edit
#schemas = Api::ApiCall::Schema.get_entities(params[:id],params)
end
def update
end
This is my Edit Form where I want to initailly retrive all data then edit and update:
<%= form_for(:schemas, url:schemas_path) do |f| %>
<%= f.text_field :schemaId, placeholder:"Schema Id"%>
<%= f.text_area :name, placeholder: "Schema Name"%>
<%= f.text_area :schemaMnemonic, placeholder: "Schema Mnemonic"%>
<%= f.text_area :Mnemonic, placeholder: "Mnemonic"%>
<%= f.text_area :description, placeholder: "Description"%>
<%= f.submit "Save"%>
<% end %>

Related

Rails 4 render action=>new does not go through new action

I have most common in rails code
def new
#company = Company.new
#companies = Company.order(:name).pluck(:name, :id)
end
def create
#company = Company.find(params["company"]["id"]) rescue nil
unless #company
render action: 'new'
return
end
status = #company.update_attributes(total_licenses: params["company"]["total_licenses"].to_i, assigned_licenses: 0)
if status == true
redirect_to users_super_admin_index_path, flash: {notice: "License has been allocated to company."}
else
render action: 'new'
end
end
but when somthing wrong it should render action new, but it directly render template hence #company remains nil and throws an error
ActionView::Template::Error (First argument in form cannot contain nil or be empty)
I want to find the permanent and right solution, no hacks please :) . And the reason why i am facing this problem.
In my view -
<%= form_for #company, url: licenses_path, method: "post" do |f| %>
<%= f.label :id, 'Select Company' %><br/>
<%= f.select :id, #companies, :include_blank => "Select Company", required: true %><br/><br/>
<%= f.label :total_licenses, 'License' %><br/>
<%= f.text_field :total_licenses, required: true%><br/><br/>
<%= f.submit 'Assign'%>
<% end %>
Remember that render(action: ...) does not actually run the method in question, it just renders out the template. You will need to manually trigger the new method to do this.

Using form_tag to pass parameters to API

I have a rails app set up as an API and another app I am using to test the API. In the test app I want the user to be able to create a new Household object which is stored in the API. Right now, when I complete the household form and submit, a new Household object is created in the API, but the "name" param is not being included. It just creates a new record with "created_at" and "updated_at" fields only. If anyone can tell me what I am doing wrong, I would appreciate it. Here is my code:
In the test app:
households/new.html.erb:
<%= form_tag households_path, :method => :post do %>
Name: <%=text_field_tag :name %><br />
<%=submit_tag 'Save' %>
<%end%>
households_controller.rb:
def create
uri = "#{API_BASE_URL}/households.json"
payload = params.to_json
rest_resource = RestClient::Resource.new(uri)
begin
rest_resource.post payload, :content_type => 'application/json'
redirect_to households_path
rescue Exception => e
redirect_to households_path
end
end
And in the API:
households_controller.rb
def create
#household = Household.new(params[:household])
if #household.save
render json: #household, status: :created, location: #household
else
render json: #household.errors, status: :unprocessable_entity
end
end
In order for your app to submit the correct params do this (look at how I named the input):
<%= form_tag households_path, :method => :post do %>
Name: <%=text_field_tag 'household[name]' %><br />
<%=submit_tag 'Save' %>
<%end%>
or instead of form_tag use form_for
<%= form_for Household.new do |f| %>
First name: <%= f.text_field :name %><br />
<%= f.submit 'Save' %>
<% end %>
If you want to check what is wrong with the way the app is right now, in your browser open the web inspector and look how your input is named (is just name and not household['name'] as you expect it on the server)
You can check it on the server too, by doing this:
def create
#household = Household.new(params[:household])
puts "params[:household] = #{params[:household]}" # this will be nil
puts "params[:name] = #{params[:name]}" #this will display what you have typed inside your input
...
end
To avoid invalid database entries validate your household:
class HouseHold < ActiveRecord::Base
validate :name, presence: true
end

Rails, user input persist when showing activerecord error message

Currently, I have text fields and some validation on the model. However, when I show the error message, all the data that was inserted by the user will be gone. I want to show the error message + the data to persist. Here is the code:
<% if #student.errors.any? %>
<div id="validation_error" class="alert alert-danger" role="alert">
<ul>
<% #student.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= form_for(:user_student, :url => {:controller => 'profile', :action => 'information'}) do |f| %>
<%= f.text_field :first_name, :value => #student.first_name, class: "form-control" , :placeholder => "First Name" %>
<%= f.text_field :last_name, :value => #student.last_name, class: "form-control" , :placeholder => "Last Name" %>
<% end %>
class Student < ActiveRecord::Base
validates :first_name, :presence => true
validates :last_name, :presence => true
end
UPDATED
Controller:
def information
#student = Student.create(check_new_student_params)
if #student.save
#redirect to other page
end
end
def check_new_student_params
params.require(:user_student).permit(:first_name, :last_name)
end
My expected behaviour: when the user give first name but not last name, it will show the error message and the first name persist on the text field. Thanks
if you have a route to a snew
you should do this
def information
#student = Student.new(check_new_student_params)
if #student.save
#redirect to other page
else
render 'new'
end
end
you're not telling rails to bring back the form after errors. and of course, you should have a new action in your controller.
Here is where your problem is. Your trying to create the object rather than assigning and trying to save. Upon save failing, you should render the page again
def information
#student = Student.new(check_new_student_params)
if #student.save
#redirect to other page
else
render original page again
end
end
def check_new_student_params
params.require(:user_student).permit(:first_name, :last_name)
end

Creating form_for for atributes User image and description

I have a rails application with devise, and I added to users a profile image, and a description. What I want to do is to create a page (DIFFERENT of the default registration/edit) where the users, after logged in, can set only this two atributes(image and description).
<%= form_for(:user, html: { method: :put, :multipart => true })) do |f| %>
<div class="form-group">
<%= f.label :Profile_Image %>
<%= f.file_field :image, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :Descrição %>
<%= f.text_area :description, class: "form-control", rows: "10" %>
</div>
<% end %>
I have already tried two different controllers and none of them worked:
def edit
end
def edit
#user = User.find(params[:id])
end
My config -> routes are:
get "edit" => "pages#edit"
post "edit" => "pages#edit"
But when i click submit it does nothing! I am new at rails and I am trying to figure this out for hours... How can I create a page to update only the image and the description? Thanks
You need an update method in your controller. Your edit method allows the form to render, but you need something like this:
def update
current_user.update(user_params)
end
Then you would have another method in your controller called user_params, which would look something like this. I was taught to put it under a private heading.
private
def user_params
params.require(:user).permit(:profile_image, :description)
end
I believe there is a shortcut way of including your params with your update method, but this will do.
Use registration controller devise and you should customize it.
You should have one method with the same name in one controller, you have two edit method. Change one edit method to update method ( reference : Allow users to edit their account )
pages_controller.rb
class PagesController < Devise::RegistrationsController
def edit
#user = current_user
end
def update
#user = current_user
successfully_updated = if needs_password?(#user, params)
#user.update_with_password(devise_parameter_sanitizer.for(:account_update))
else
params[:user].delete(:current_password)
#user.update_with_password(devise_parameter_sanitizer.for(:account_update))
end
if successfully_updated
set_flash_message :notice, :updated
# Sign in the user bypassing validation in case his password changed
sign_in #user, :bypass => true
redirect_to after_update_path_for(#user)
else
render "edit"
end
end
private
def needs_password?(user, params)
user.email != params[:user][:email] || params[:user][:password].present?
end
end
application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_filter :configure_permitted_parameters, if: :devise_controller?
def configure_permitted_parameters
devise_parameter_sanitizer.for(:account_update) do |u|
u.permit(:description, :image, :email, :password, :password_confirmation)
end
end
end
You have wrong http verb (post), you need PUT/PATCH not POST
devise_scope :user do
get "edit" => "pages#edit"
put "update" => "pages#update"
end
On your view looks like (example and not tested)
<%= form_for(#user, :url => update_pages_path, :html => { :method => :put }) do |f| %>
<%= devise_error_messages! %>
<div class="form-group">
<%= f.label :image, "Profile Image" %>
<%= f.file_field :image, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label description, "Descrição" %>
<%= f.text_area :description, class: "form-control", rows: "10" %>
</div>
<% end %>
<%= f.submit "Save Image" %>

Pass model between controllers and views in Ruby on Rails

I have signup form on my home screen. If user inputs invalid data I redirect him to /signin page. On this page I can see filled fields, but errors descriptions are empty.
Here is my UsersController:
class UsersController < ApplicationController
def new
#user = User.new(params[:user])
end
def create
#user = User.new(params[:user])
print #user
if #user.save
else
render 'new'
end
end
end
Method I use to show errors
module ApplicationHelper
def errors_for(model, attribute)
if model.errors[attribute].present?
content_tag :div, :class => 'well error' do
content_tag :ul do
model.errors[attribute].collect {|item| concat(content_tag(:li, item))}
end
end
end
end
end
My form partial:
<%= f.label :user_name %>
<%= f.text_field :user_name, :class=>"input-medium" %>
<%= errors_for(#user, :user_name) %>
<%= f.label :email %>
<%= f.text_field :email, :class=>"input-medium " %>
<%= errors_for(#user, :email) %>
<%= f.label :password %>
<%= f.password_field :password, :class=>"input-medium" %>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation, :class=>"input-medium" %>
and my signup view:
<section class="centered user-form-container">
<div class="user-form well pull-left">
<div class="centered">
<h1>Sign up</h1>
<%= form_for(#user, :action=>"create") do |f| %>
<%= render 'signup', :f=>f %>
<%= f.submit "Sign up" %>
<% end %>
</div>
</div>
</section>
In this situation, I believe you need to use flash.now, something like this:
Per the rails docs:
By default, adding values to the flash will make them available to the next request, but sometimes you may want to access those values in the same request. For example, if the create action fails to save a resource and you render the new template directly, that’s not going to result in a new request, but you may still want to display a message using the flash. To do this, you can use flash.now in the same way you use the normal flash:
def create
#user = User.new(params[:user])
print #user
if #user.save
else
# start with this, then expand the error text
flash.now[:error] = "Could not save user"
render 'new'
end
end
You would do this in your validation method.
If you are using a standard rails validation you would do this:
validates_presence_of :foo, :message => 'Message you want to display here'
If you are doing a custom validation then this:
def my_validation_method
begin
my_validation_code_here
rescue
self.errors[:base] << 'Message you want to display here'
end
end
def new
#user = User.new(params[:user])
if (!params[:user].nil?)
#user.valid?
end
end

Resources