Rails | show url parameters on show page after create - javascript

I added the URL parameters to the new.html.erb page by a link_to
<%= link_to 'Message', new_personal_message_path(receiver_id: 1010) %>
which correctly to displayed in the URL as
example.com/personal_messages/new?receiver_id=1010
and i was able to than reference it in my controller by simple #receiver = User.find_by(id: params[:receiver_id])
On the new.html.erb i have this form to create a new conversation:
<%= form_for #personal_message do |f| %>
<%= hidden_field_tag 'receiver_id', #receiver.id %>
<%= f.text_area :body, class: "personal_message_textarea", placeholder: "Chat with us...", :autofocus => true %>
<%= hidden_field_tag :conversation_id, params[:id] || session[:conversation_id] %>
<%= f.submit " ", placeholder: "Chat with us!", class: "personal_message_submit" %>
<% end %>
And it'll automatically redirect the user to the show page which the url displays as
example.com/conversations/1
But I also want it to also show the newly created user_id (I have a method in my controllers that automatically creates a user account on create) in the URL parameters like so:
example.com/conversatinos/1?user_id=23&receiver_id=1010
the new method in personal_messages controller
def new
redirect_to conversation_path(#conversation) and return if #conversation
#personal_message = PersonalMessage.new
#site = Site.find_by(id: cookies[:siteid]) #used to pull site description
end
create method in personal_messages controller
def create
#conversation ||= Conversation.create(author_id: cookies[:user_id],
receiver_id: #receiver.id)
#personal_message = current_user.personal_messages.build(personal_message_params)
#personal_message.conversation_id = #conversation.id
#personal_message.save!
flash[:success] = "ok!"
redirect_to conversation_path(#conversation)
end

fixed: personal_messages controllers
def create
#conversation ||= Conversation.create(author_id: cookies[:user_id],
receiver_id: #receiver.id)
#personal_message = current_user.personal_messages.build(personal_message_params)
#personal_message.conversation_id = #conversation.id
#personal_message.save!
flash[:success] = "ok!"
#redirect_to conversation_path(#conversation)
redirect_to conversation_path(#conversation, user_id: current_user.id, receiver_id: #receiver)
end

Related

Rails submitting a form through ajax

There is some problem with using ajax in rails. I want to create new post in my wellcome/inex page. But when I push the botton it show
No route matches [POST] "/welcome/index"
wellcome/index.html
<b>Projects</b>
<ul id="projects">
<% #projects.each do |project| %>
<h2><%= project.title %></h2>
<% end %>
</ul>
<br>
<%= form_for :project do |f| %>
<%= f.text_field :title, :placeholder => ' Enter new project here..' %>
<but><%= f.submit 'Add Project'%></but>
<% end %>
welcome_controller.rb
class WelcomeController < ApplicationController
def index
#projects = Project.all
#project = Project.new
end
def create
#project = Project.new(project_params)
respond_to do |format|
if #project.save
format.html { redirect_to #project, notice: 'project was successfully created.' }
format.js
format.json { render json: #project, status: :created, location: #project }
else
format.html { render action: "new" }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
end
private
def project_params
params.require(:project).permit(:title)
end
end
create.js.erb
$('#projects').html("<%= escape_javascript (render 'projects') %>");
routes project
Prefix Verb URI Pattern Controller#Action
project_index GET /project(.:format) project#index
POST /project(.:format) project#create
new_project GET /project/new(.:format) project#new
edit_project GET /project/:id/edit(.:format) project#edit
project GET /project/:id(.:format) project#show
PATCH /project/:id(.:format) project#update
PUT /project/:id(.:format) project#update
DELETE /project/:id(.:format) project#destroy
Spent a lot of time updating this with AJAX but failed everytime. Any there to help? Thanks in advance
You have to add remote: true into form.
<%= form_for #project, url: project_index_path, remote: true do |f| %>
<%= f.text_field :title, :placeholder => ' Enter new project here..' %>
<but><%= f.submit 'Add Project'%></but>
<% end %>
If you want integrate Ajax and Ruby you need to add the line below inside your link action
remote:true
also you can check this about Ajax and Ruby
How Ajax works with ruby on rails

How do I render a partial containing a form_for for an edit function?

I have a div in a parent view that renders a show partial. In this show partial, I have a button that should change the parent's partial to render the 'form' partial to edit the object, but I keep getting jammed up because it seems that the 'form' partial's form_for is missing the #project object.
How can I pass this object to the 'form' partial? Am I missing something else?
I am rather new to using AJAX. Happy to provide more information if you need.
The error I am getting in the server terminal is
ActionView::Template::Error (First argument in form cannot contain nil or be empty):
routes.rb
get 'switchProjectView', to: 'projects#switch_main_view'
resources :projects
projects_controller.rb
class ProjectsController < ApplicationController
def new
#project = Project.new
end
def create
#project = Project.new(project_params)
if #project.save
flash[:success] = "New Project Added"
redirect_to #project
else
flash[:danger] = "Project Not Added. Please Try Again"
end
end
def show
#project = Project.find(params[:id])
end
def index
#projects = Project.all
end
def update
#project = Project.find(params[:id])
if #project.update_attributes(project_params)
redirect_to #project
else
render 'edit'
end
end
def edit
end
def switch_main_view
respond_to do |format|
format.html
format.js
end
end
def project_params
params.require(:project).permit(:main_contact_name, :id, :main_contact_phone, :main_contact_email, :project_name)
end
end
show.html.erb
<div class="body">
<div class="center jumbotron heading-jumbo">
<h1><%= #project.project_name %></h1>
</div>
<div class="body-jumbo jumbotron" id='project-details'>
<%= render "projects/show" %>
</div>
</div>
switch_main_view.js.erb
$('#project-details').html("<%= j render :partial => 'projects/form' %>");
_form.html.erb
<%= form_for(#project) do |f| %>
<%= f.label :project_name %>
<%= f.text_field :project_name, class: 'form-control'%>
<%= f.label :main_contact_name %>
<%= f.text_field :main_contact_name, class: 'form-control'%>
<%= f.label :main_contact_phone %>
<%= f.text_field :main_contact_phone, class: 'form-control'%>
<%= f.label :main_contact_email %>
<%= f.text_field :main_contact_email, class: 'form-control'%>
<%= f.submit 'Save Project', class: 'btn btn-primary'%>
<% end %>
_show.html.erb
<div class='text-center center'>
<h3><strong>Project Information</strong></h2>
</div>
<h2>Start Date: Launch Date:</h1>
<span class='pull-right jumbo-btn-span'><%= link_to "Edit Project Information", switchProjectView_path(#project), remote: true, class:'btn btn-primary jumbo-btn' %></span>
<h2>Primary Conact's Name: <%= #project.main_contact_name %></h2>
<h2>Primary Conact's Phone: <%= #project.main_contact_phone %></h2>
<h2>Primary Conact's Email: <%= #project.main_contact_email %></h2>
Well, with each request, you need to re-initialize the variable in your controller method. In your case, you need to do the following:
def switch_main_view
#project = Project.new
respond_to do |format|
format.html
format.js
end
end
Doing so will enable you to get rid of the error: First argument in form cannot contain nil or be empty, but that won't enable you to do what you are actually trying to do.
When you use link_to, by default it goes for an HTML request as you can see in Rails logs, something like following will appear:
Processing by ProjectsController#switch_main_view as HTML
In order to get the JS response, you need to tell link_to that you are up for a JS response, not for an HTML response, and you can do by passing format: :js in link_to like:
<%= link_to "Edit Project Information", switchProjectView_path(#project, format: :js), remote: true, class:'btn btn-primary jumbo-btn' %></span>
remote: true will be there to make sure that you aren't reloading the contents of the page, rather you are trying to fetch something from the server in the background.
Your request "switchProjectView_path(#project)" only send object id to server, so you need to load the object to present it in view for response.
1. First the route should look like this so that, the url could contain object id:
get 'switchProjectView/:id', to: 'projects#switch_main_view', as:"switchProjectView"
2. You have to load the object in controller:
def switch_main_view
#project = Project.find(params[:id])
respond_to do |format|
format.html
format.js
end
end
Try passing the variable when calling the partial:
$('#project-details').html("<%= j render :partial => 'projects/form', locals: {project: #project} %>");

Unpermitted parameter: songs_attributes

I have a problem with my nested attributes. I want someone to be able to just visit my website and add songs to an event. They can only add those songs if they supply a partycode for that event. I have my nested attributes set up correctly I think but I am getting an unpermitted paramter error.
Events controller:
class EventsController < ApplicationController
def new
#event = Event.new
#event.songs.build
end
def show
#event = Event.find(params[:id])
#songs = #event.songs.paginate(page: params[:page])
end
def create
#event = current_user.events.build(event_params)
if #event.save
flash[:success] = "Event Created!"
redirect_to user_path(#event.user)
else
render 'welcome/index'
end
end
def destroy
end
private
def event_params
params.require(:event).permit(:name, :partycode, song_attributes: [:artist, :title, :genre, :partycode])
end
end
application_controller:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
include SessionsHelper
end
Here is the new.html.erb file in the songs view, which contains the code to add songs to the event, note that the user is not signed in when they are adding songs:
<br>
<br>
<div class ="container">
<div class="jumbotron">
<%= form_for Event.new do |f| %>
<h3>Enter a song:</h3>
<%= f.fields_for :songs, Song.new do |song_form| %>
<%= song_form.collection_select(:event_id, Event.all, :id, :name) %>
<%= song_form.text_field :artist, placeholder: "Artist" %>
<%= song_form.text_field :title, placeholder: "Title" %>
<%= song_form.text_field :genre, placeholder: "Genre" %>
<% end %>
<%= link_to_add_fields "Add Song", f, :songs %>
<%= f.text_field :partycode %>
<%= f.submit "Submit", class: "btn btn-primary" %>
<% end %>
</div>
</div>
The link_to_add_fields method is in the application_helper.rb file:
module ApplicationHelper
def link_to_add_fields(name, f, association)
new_object = f.object.send(association).klass.new
id = new_object.object_id
fields = f.fields_for(association, new_object, child_index: id) do |builder|
render("songs_fields", f: builder)
end
link_to(name, '#', class: "add_fields", data: {id: id, fields: fields.gsub("\n", "")})
end
end
The songs_field partial is defined as follows:
<fieldset>
<%= f.text_field :artist, placeholder: "Artist" %>
<%= f.text_field :title, placeholder: "Title" %>
<%= f.text_field :genre, placeholder: "Genre" %>
</fieldset>
The coffee-script that adds the fields:
$(document).on 'click', 'form .add_songs', (event) ->
time = new Date().getTime()
regexp = new RegExp($(this).data('event_id'), 'g')
$(this).before($(this).data('songs').replace(regexp, time))
event.preventDefault()
The person from the new.html.erb page will be able to select a event from the drop down menu then on demand add more fields that are for a song and then enter a partycode for the certain event that they picked. Any help on this would be fantastic! Thanks
EDIT error:
undefined method `events' for nil:NilClass
In your EventsController, your nested params is spelled as song_attributes in event_params method
private
def event_params
params.require(:event).permit(:name, :partycode, song_attributes: [:artist, :title, :genre, :partycode])
end
But your error says unpermitted parameter: songs_attributes.
You spelled it incorrect.Change your event_params method in EventsController as follows
private
def event_params
params.require(:event).permit(:name, :partycode, songs_attributes: [:artist, :title, :genre, :partycode])
end

Rails: What is wrong with this logic of trying to render a parial on click?

I'm trying to get the activities when the user clicks on a button called display
Controller:
def display
#activities = Activity.all
#activities = Activity.order("created_at desc")
#we will need to find the Post id Through Users relation to the Comments
#And this is because Activity Track, tracks Users actions, it breaks down from there.
#posts = Post.all
#user_comments = UserComment.all
respond_to do |format|
format.js { #activities = Activity.order("created_at desc") }
end
View:
<%= link_to "Display", activities_path, :remote => true %>
<div id="notify" class="section-link">
</div>
display.js.erb
$('#notify').append("<%= escape_javascript(render :partial => 'layouts/activity') %>");
_activity.html.erb
<% #activities.each do |activity| %>
<%= ActivityPresenter.new(activity, self).render_activity %>
<% end %>
Try this in display.js.erb:
$('#notify').append('<%= escape_javascript(render :partial => 'layouts/activity', :collection => #activities) %>');
Then, try this in _activity.html.erb:
<%= ActivityPresenter.new(activity, self).render_activity %>
To ensure that whenever the user clicks on "Display' the display action is invoked, you will need to adjust your routes.rb file, which is located in the config directory. You could do something like this in routes.rb:
get '/activities/display', 'activities#display', as: :activity_display
Once you make that change in routes.rb, you can edit your link_to like this:
<%= link_to "Display", activity_display_path, :remote => true %>

Ajax/Rails Nested Comments

I have an application where book_comments belongs_to books.
My routes file :
resources :books do
resources :book_comments
end
I have a book_comment form on show.html.erb for books.
def show
#book = Book.find(params[:id])
#new_book_comment = #book.book_comments.build
end
I'm using ajax to post the book_comments to the book show page via a partial: _book_comment_form.html.erb :
<%= form_for([#book, #new_book_comment], remote: :true) do |f| %>
<div class="field" style="margin-top:60px;">
<%= f.text_area :comment, rows: 3 %>
<%= f.submit "Add Comment" %>
</div>
<% end %>
When #new_book_comment is called it refers to a book_comments_controller create action:
def create
#book = Book.find(params[:book_id])
#book_comment = current_user.book_comments.build(params[:book_comment]) do |f|
f.book_id = #book.id
end
if #book_comment.save
respond_to do |format|
format.html { redirect_to #book }
format.js { render :layout => false }
end
end
end
The book_comment is saved but my problem comes in when trying to render via ajax in the _book_comments partial:
<div id="comments">
<% #book_comments.each do |book_comment| %>
<%= render 'comment', :book_comment => comment %>
</div>
<% end %>
</div>
via: create.js.erb in the book_comments folder
$("div#comments").append("<%= escape_javascript(render('books/comment'))%>")
To sum, I'm having trouble making the create.js.erb in book_comments render to the book show page. Why wouldn't create.js.erb in the book_comments folder know to look at the objects in the and infer the new book comment should go inside the div?
My error message:
undefined method `comment' for nil:NilClass
don't understnd why. Seeing that I'm passing the instance variable to the comment partial.
Your partial's doing it wrong. You're passing a not referenced value (comment) to a not used variable (book_comment).
Instead of:
<% #book_comments.each do |book_comment| %>
<%= render 'comment', :book_comment => comment %> ....
you should do:
<% #book_comments.each do |book_comment| %>
<%= render 'comment', :comment => book_comment %>

Categories

Resources