Create multiple records with one form submit - ruby-on-rails

I have 3 models: User, Ingredient, and a map of which user has which ingredients - UserIngredient.
My current setup works for adding 1 ingredient at a time. What I want is to update the code so that users can enter a few ingredients and just click "submit" once rather than clicking it for each ingredient individually. I've looked into nested_resources but it seems like not the right place to use it.
what is the right way of doing this?
thank you
app/models/user.rb
class User < ApplicationRecord
...
has_many :user_ingredients, dependent: :destroy
has_many :ingredients, through: :user_ingredients
...
end
app/models/ingredient.rb
class Ingredient < ApplicationRecord
...
has_many :user_ingredients, dependent: :destroy
has_many :owners, through: :user_ingredients
...
end
app/models/user_ingredient.rb
class UserIngredient < ApplicationRecord
belongs_to :user
belongs_to :ingredient
validates :user, presence: true
validates :ingredient, presence: true
end
app/views/user_ingredients/new.html.erb
<div>
<%= turbo_frame_tag #user_ingredient do %>
<%= render "form", user_ingredient: #user_ingredient %>
<% end %>
</div>
app/views/user_ingredients/_form.html.erb
<div class="w-full mx-auto">
<%= form_for #user_ingredient do |f| %>
<div class="flex-row gap--md">
<%= f.select(
:ingredient_id,
options_from_collection_for_select(Ingredient.where(id: f.object.ingredient_id), :id, :name, :selected => f.object.ingredient_id),
{ prompt: 'Start typing to search' },
{ id: "drDwn_ingredient",
class: "w-full border border-black",
required: true,
data: {
controller: "selectIngredient",
selectIngredient_url_value: autocomplete_ingredients_path,
},
}) %>
<div class="flex-row gap--xxxs">
<label>
<input type="submit" class="add_cancel_ing gap--md" />
<%= inline_svg_tag "svg/circle-check.svg", class: "svg_add_ing" %>
</label>
<%= link_to user_ingredients_path do %>
<%= inline_svg_tag "svg/circle-xmark.svg", class: 'svg_cancel_ing' %>
<% end %>
</div>
</div>
<% end %>
</div>
app/controllers/user_ingredients_controller.rb
class UserIngredientsController < ApplicationController
before_action :authenticate_user!
before_action :set_user_ingredient, only: [:show, :destroy]
def index
#user_ingredients = current_user.user_ingredients
end
def new
#user_ingredient = UserIngredient.new
end
def create
#user_ingredient = UserIngredient.new(user_ingredient_params.merge(user: current_user))
if #user_ingredient.save
respond_to do |format|
format.html { redirect_to user_ingredients_path, notice: 'Ingredient was successfully added to your bar!' }
format.turbo_stream { flash.now[:notice] = 'Ingredient was successfully added to your bar!' }
end
else
render :new
end
end
def destroy
#user_ingredient.destroy
respond_to do |format|
format.html { redirect_to user_ingredients_path, notice: "Ingredient was removed!" }
format.turbo_stream { flash.now[:notice] = "Ingredient was removed!" }
end
end
private
...
def set_user_ingredient
#user_ingredient = current_user.user_ingredients.find(params[:id])
end
def user_ingredient_params
params.require(:user_ingredient).permit(:id, :ingredient_id)
end
end
app/javascript/controllers/selectIngredient_controller.js
import { Controller } from "#hotwired/stimulus";
import { get } from "#rails/request.js";
import TomSelect from "tom-select";
export default class extends Controller {
static values = { url: String };
multi_select_config = function () {
return {
plugins: ["remove_button", "no_active_items"],
valueField: "value",
load: (q, callback) => this.search(q, callback),
closeAfterSelect: true,
persist: false,
create: false,
};
};
async search(q, callback) {
const response = await get(this.urlValue, {
query: { q: q },
responseKind: "json",
});
if (response.ok) {
const list = await response.json;
callback(list);
} else {
console.log("Error in select_ctrl: ");
console.log(response);
callback();
}
}
connect() {
new TomSelect(this.element, this.multi_select_config());
}
}

You should use accepts_nested_attributes_for method for User
And try to create related records via User.
https://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html
Or you can try to make custom action for accepting custom form with multiple records at once. But first option will be more predictable and easier for supporting.
For views you can use cocoon gem. It's pretty old, but it still works good.
Or you can inspire by it and make your custom solution)
https://github.com/nathanvda/cocoon

Related

Auto-complete suggestion within a simple_form

I am building an application where i try to suggest "Similar topics" in rails, as the user put the title of his/her new story.
I have 2 problems:
The controller with the custom action does not work at all. it seems that the server simply retrieves the view. Without running any of the code in the action
To go around the issue of the controller, i created a service.rb with a function to retrieve the records based on the params[:title], but from here I do NOT know how to make small popup window with suggestions (and weblinks) as the user write the title of the topic.
I have done so far :
View
<div class="col-md-12">
<%= simple_form_for #message do |f| %>
<div style="font-size: xx-small; font-style: italic; color: #44B5EB">
<%= f.input :title, label: "#{t :Title}", placeholder: "#{t :Search}", id: "title" , data: {behavior: "autocomplete_message"}%>
<%= f.cktext_area :description, label: "#{t :Message_body}", :input_html => {:rows => 25} %>
<br> <br>
<%= f.submit "#{t :Create_story}", class: "btn btn-primary"%>
<% end %>
</div>
</div>
<script>
$("#title").addEventListener("turbolinks:load", function () {
$input = $("[data-behavior = 'autocomplete_message']");
var options = {
getValue: "name",
url: function (phrase) {
return "messages/search.json?title=" + phrase;
},
categories: [
{
listLocation: "qandas",
header: "<p class='Search_drop_separate'>Q&A </p>",
}
],
list: {
onChooseEvent: function(){
var url = $input.getSelectedItemData().url;
$input.val("");
Turbolinks.visit(url)
}
}
};
$input.easyAutocomplete(options)
});
</script>
Controller
class StorytController < ApplicationController
before_action :authenticate_user!
before_action :find_message, only: [:show, :edit, :update, :destroy]
respond_to :html, :js
...
def search
##qandasquestions = Qandasquestion.ransack(question_or_answer_cont: params[:q]).result(distinct: true)
respond_to do |format|
format.html {
#qandasquestions = #qandasquestions
redirect_to stories_search_path
}
format.json {
#qandasquestions = #qandasquestions.limit(5)
}
end
end
def full_name
"#{first_name} #{last_name}"
end
private
def force_json
request.format = :json
end
end
Search.jason.builder
json.qandas do
json.array!(#qandasquestions) do |qandasquestion|
json.name "#{qandasquestion.question}"
json.url qanda_path(qandasquestion.qanda_id)
end
end
routes:
get 'stories/search'
What I am looking to build is actually very similar to what we have on Stackoverflow on the principle.
Anybody did something similar and can help me please?
I don't mean to sidetrack you but if you have a couple minutes to check this out, have you seen select2? It works nice with Rails and there's also a gem to make it work nice with simple_form
https://github.com/lndl/select2_simple_form

Convert string into integer in rails

I'm creating a form_for in which one of the field fetches the drop-down list from the database. I'm interpolating the data to display the string but I want to store its id back into other database which is linked with my form.
class FlightsController < ApplicationController
def new
#flight = Flight.new
#airplane = #flight.airplane
#options = Airport.list
end
def create
#flight = Flight.new(flight_params)
if #flight.save!
flash[:success] = "Flight created successfully."
redirect_to #flight
else
flash[:danger] = "Flight not created."
redirect_to :new
end
end
private
def flight_params
params.require(:flight).permit(:name, :origin, :destination, :depart, :arrive, :fare, :airplane_id)
end
end
<%= form_for(#flight) do |f| %>
...
<div class="row">
<div class="form-group col-md-6">
<%= f.label :origin %>
<%= f.select :origin, grouped_options_for_select(#options), { include_blank: "Any", class: "form-control selectpicker", data: { "live-search": true } } %>
</div>
</div>
...
<% end %>
class Airport < ApplicationRecord
def self.list
grouped_list = {}
includes(:country).order("countries.name", :name).each do |a|
grouped_list[a.country.name] ||= [["#{a.country.iso} #{a.country.name}", a.country.iso]]
grouped_list[a.country.name] << ["#{a.iata} #{a.name} (#{a.city}, #{a.country.name})", a.id]
end
grouped_list
end
end
class Flight < ApplicationRecord
belongs_to :origin, class_name: "Airport"
belongs_to :destination, class_name: "Airport"
belongs_to :airplane
has_many :bookings, dependent: :destroy
has_many :passengers, through: :bookings
end
The following error is showing,
Airport(#69813853361360) expected, got "43" which is an instance of String(#47256130076180)
The output of Airport.list when run in a console is shown below:
=> {"India"=>[["IN India", "IN"], ["AGX Agatti Airport (Agatti, India)", 3], ["IXV Along Airport (Along, India)", 5], ["AML Aranmula International Airport (Aranmula, India)", 6], ["IXB Bagdogra International Airport (Siliguri, India)", 50]]}
Parameters: {"utf8"=>"✓", "authenticity_token"=>"+Z8+rkrJkkgaTznnwyTd/QjEoq3kR4ZmoUTp+EpM+320fNFg5rJm+Izx1zBODo/H7IIm3D+yg3ysnVUPmy7ZwQ==", "flight"=>{"name"=>"Indigo", "origin"=>"49", "destination"=>"11", "depart"=>"2019-02-21T21:30", "arrive"=>"2019-02-22T01:30", "fare"=>"2500", "airplane_id"=>"3"}, "commit"=>"Create Flight"}
I tried using to_i but it didn't work.
if you're interpolating a string with space delimiter you can try this.
'1 one'.split(' ').first.to_i
grouped_options_for_select is sending a.id as string value. Convert it to integer in your create action.
def create
#flight = Flight.new(flight_params)
#flight.origin = #flight.origin.to_i ## <== add this line
if #flight.save!
...
Convert string into integer in rails:
user_id = "123"
#user_id = user_id.to_i
puts #user_id
#user_id = 123
Convert integer into string in rails:
user_id = 456
#user_id = user_id.to_s
puts #user_id
#user_id = "456"
Convert column type string into integer in rails migration :
def change
change_column :webinars, :user_id, :integer, using: 'user_id::integer'
end
Convert column type integer into string in rails migration:
def change
change_column :webinars, :user_id, :string, using: 'user_id::string'
end
Your problem is not integer versus string, your problem is (and the error is telling you) the field is expecting an Airport object, but it's getting an airport id...
<%= f.select :origin, grouped_options_for_select(#options), { include_blank: "Any", class: "form-control selectpicker", data: { "live-search": true } } %>
You're trying to select origin which is an airport object. You really are just returning the ID of an airport object (origin_id).
Change it to
<%= f.select :origin_id, grouped_options_for_select(#options), { include_blank: "Any", class: "form-control selectpicker", data: { "live-search": true } } %><%= f.select :origin, grouped_options_for_select(#options), { include_blank: "Any", class: "form-control selectpicker", data: { "live-search": true } } %>
And don't forget to update your flight_params
def flight_params
params.require(:flight).permit(:name, :origin_id, :destination, :depart, :arrive, :fare, :airplane_id)
end
I would guess you'll have a similar problem with destination

Rails4 advice: How should I create multiple records in a model from single view?

Been struggling with this query for a few days. I have 3 models Books, Children and Hires. I have created a view for hires which allows a user to select 2 books and a single child and what i'm looking to do is insert two rows to reflect this into the 'hires' table. I have some JS that populates the hidden fields with the values that they require. Now, I don't think nested attributes is the way to go, because i'm trying to insert directly into the joining table.
So, what i'm trying now is the following:
hires/_form.html.erb
<%= form_for(#hire) do |f| %>
<% 2.times do %>
<%= f.hidden_field :child_id %>
<%= f.hidden_field :book_id %>
<% end %>
<%= f.submit 'Take me home' %>
<% end %>
and then what I want to do is to run through the 'create' function twice in my controller and thus create two rows in the 'hires' model. Something like this:
hires_controller.rb
def create
hire_params.each do |hire_params|
#hire = Hire.new(hire_params)
end
end
Is this completely the wrong way to go? I'm looking for advice on the right way to do this? If this will work, what's the best way to format the create statement?
** Edit **
I have 3 models. Each Child can have 2 books. These are my associations:
class Child < ActiveRecord::Base
has_many :hires
has_many :books, through: :hires
end
class Hire < ActiveRecord::Base
belongs_to :book
belongs_to :child
accepts_nested_attributes_for :book
accepts_nested_attributes_for :child
end
class Book < ActiveRecord::Base
has_many :hires
has_many :children, through: :hires
belongs_to :genres
end
hires/new.html.erb
<div class="form-inline">
<div class="form-group">
<h1><label for="genre_genre_id">Pick Book 1:
<%=collection_select(:genre1, :genre_id, #genres.all, :id, :Name, {prompt: true}, {:class => "form-control dropdown"})%></label></h1>
</div>
</div>
<div id="book1-carousel" class="owl-carousel owl-theme">
<% #books.each do |book| %>
<div data-id = "<%= book.id %>" class="tapbook1 tiles <% #genres.each do |g|%> <% if g.id == book.Genre_id %> book1genre<%=g.id %> <% end end%> <%= %>"><a class="item link"><% if book.bookimg.exists? %><%= image_tag book.bookimg.url(:small), :class => "lazyOwl", :data => { :src => book.bookimg.url(:small)}%> <%end%></br><p class="tile_title" ><%= book.Title %></p></a></div>
<% end %>
</div>
<div class="form-inline">
<div class="form-group">
<h1><label for="genre_genre_id">Pick Book 2:
<%=collection_select(:genre2, :genre_id, #genres.all, :Name, :Name, {prompt: true}, {:class => "form-control dropdown"})%></label></h1>
</div>
</div>
<div id="book2-carousel" class="owl-carousel owl-theme">
<% #books.each do |book| %>
<div data-id = "<%= book.id %>" id="<%= book.id %>" class="tapbook2 tiles <% #genres.each do |g|%> <% if g.id == book.Genre_id %> book2genre<%=g.id %> <% end end%> <%= %>"><a class="item link"><% if book.bookimg.exists? %><%= image_tag book.bookimg.url(:small) , :class => "lazyOwl", :data => { :src => book.bookimg.url(:small)}%> <%end%></br> <p class="tile_title"><%= book.Title %></p></a></div>
<% end %>
</div>
<h1 class="child_heading1" >Now choose your name:</h1>
<div id="children-carousel" class="owl-carousel owl-theme">
<% #children.each do |child| %>
<div data-id = "<%= child.id %>" class="tapchild tiles"><a class="item link"><% if child.childimg.exists? %><%= image_tag child.childimg.url(:small), :class => "lazyOwl", :data => { :src => child.childimg.url(:small)} %> <%end%></br> <p class="tile_title"><%= child.nickname %></p></a></div>
<% end %>
</div>
<%= render 'form' %>
and the coffeescript:
hires.coffee
$(document).on 'ready page:load', ->
book1carousel = $("#book1-carousel")
book2carousel = $('#book2-carousel')
book1carousel.owlCarousel items: 5, lazyLoad : true
book2carousel .owlCarousel items: 5, lazyLoad : true
$('#children-carousel').owlCarousel items: 5, lazyLoad : true
book1clickcounter = 0
book2clickcounter = 0
childclickcounter = 0
book1selection = 0
book2selection = 0
$('.tapbook1').on 'click', (event) ->
$this = $(this)
book1id = $this.data('id')
book1selection = book1id
if $this.hasClass('bookclicked')
$this.removeAttr('style').removeClass 'bookclicked'
book1clickcounter = 0
$('#hire_book_id').val("");
book1selection = 0
else if book1clickcounter == 1
alert 'Choose one book from this row'
else if book1selection == book2selection
alert "You've already picked this book"
else
$('#hire_book_id').val(book1id);
$this.css('border-color', 'blue').addClass 'bookclicked'
book1clickcounter = 1
return
$('.tapbook2').on 'click', (event) ->
$this = $(this)
book2id = $this.data('id')
book2selection = book2id
if $this.hasClass('book2clicked')
$this.removeAttr('style').removeClass 'book2clicked'
book2clickcounter = 0
book1selection = 0
else if book2clickcounter == 1
alert 'Choose one book from this row'
else if book1selection == book2selection
alert "You've already picked this book"
else
$this.css('border-color', 'blue').addClass 'book2clicked'
book2clickcounter = 1
return
$('.tapchild').on 'click', (event) ->
$this = $(this)
childid = $this.data('id')
if $this.hasClass('childclicked')
$this.removeAttr('style').removeClass 'childclicked'
childclickcounter = 0
$('#hire_child_id').val("");
else if childclickcounter == 1
alert 'Choose one child from this row'
else
$this.css('border-color', 'blue').addClass 'childclicked'
childclickcounter = 1
$('#hire_child_id').val(childid);
return
jQuery ($) ->
$('td[data-link]').click ->
window.location = #dataset.link
return
return
return
My approach to this would be what's called a form object, a class that acts like a model but exists only to handle the creation of multiple objects. It provides granular control, but at the expense of duplicating validations. In my opinion (and that of many others), it's a much better option than nested attributes in most cases.
Here's an example. Note that I don't have any idea what your application does, and I didn't look at your associations close enough to make them accurate in this example. Hopefully you'll get the general idea:
class HireWithBookAndChild
include ActiveModel::Model
attr_accessor :child_1_id, :child_2_id, :book_id
validates :child_1_id, presence: true
validates :child_2_id, presence: true
validates :book_id, presence: true
def save
if valid?
#hire = Hire.new(hire_params)
#child_1 = #hire.child.create(id: params[:child_1_id])
#child_2 = #hire.child.create(id: params[:child_2_id])
#book = #hire.book.create(id: params[:book_id])
end
end
end
By including AR::Model, you get validations and an object you can create a form with. You can even go into your i18n file and configure the validation errors messages for this object. Like an ActiveRecord model, the save method is automatically wrapped in a transaction so you won't have orphaned objects if one of them fails to persist.
Your controller will look like this:
class HireWithBookAndChildController < ApplicationController
def new
#hire = HireWithBookAndChild.new
end
def create
#hire = HireWithBookAndChild.new(form_params)
if #hire.save
flash['success'] = "Yay"
redirect_to somewhere
else
render 'new'
end
end
private
def form_params
params.require(:hire_with_book_and_child).permit(:child_1_id, :child_2_id, :book_id)
end
end
Your form will look like this:
form_for #hire do |f|
f.hidden_field :child_1_id
...
f.submit
end
You'll notice right away that everything is flat, and you aren't having to mess with fields_for and nested nested parameters like this:
params[:child][:id]
You'll find that form objects make your code much easier to understand. If you have different combinations of children, books and hires that you need to create, just make a custom form object for each one.
Update
A solution that might be more simple in this case is to extract a service object:
class TwoHiresWithChildAndBook < Struct.new(:hire_params)
def generate
2.times do
Hire.create!(hire_params)
end
end
end
And from your controller:
class HiresController
def create
generator = HireWitHChildAndBook.new(hire_params)
if generator.generate
*some behavior*
else
render :new
end
end
end
This encapulates the knowledge of how to create a hire in one place. There's more detail in my answer here: Rails 4 Create Associated Object on Save

Multiple Select Tag in Rails

Im trying to implement a multiple level drop down list in Rails
I have three Tables in my DB.
vehicle_make.rb
class VehicleMake < ActiveRecord::Base
validates_uniqueness_of :make
has_many :appointments
end
vehicle_model.rb
class VehicleModel < ActiveRecord::Base
validates_uniqueness_of :model
has_many :appointments
end
vehicle_make_model.rb
class VehicleMakeModel < ActiveRecord::Base
validates_uniqueness_of :vehicle_make_id, :scope => :vehicle_model_id
end
and im trying to implement a multiple dropdown list in appointments.html.rb
on selecting the vehicle model only corresponding make should load..
<%= f.select :vehicle_make_id, options_for_select(vehicle_make.map {|s| [s.make, s.id]}, appointment.vehicle_make_id), {}, {class: "form-control"} %>
and in my js i have..
$('#appointment_vehicle_make_id').on('change', function() {
var vehicle_make_id = this.value;
$.ajax({
url : '/appointments/update_models',
type : 'GET',
data : {
make_id : vehicle_make_id
},
success : function(response) {
console.log(response);
}
});
});
and this is my controller method.
def update_models
#vehicle_models = VehicleModel.all
#model_ids = []
#selected_vehicle_models = VehicleMakeModel.where(vehicle_make_id: params[:make_id]).order(:vehicle_model_id) unless params[:make_id].blank?
#selected_vehicle_models.each do |t|
#model_ids << t.vehicle_model_id
end
respond_to do |format|
format.html { render layout: false }
format.js
end
end
I have html page named update_models.html.erb associated to the above action.
<%= select_tag :vehicle_model_id, options_for_select(#model_ids.map {|s| [s.model, s.first.id]}, nil), {}, {class: "form-control"} %>
I get an error in terminal saying
ActionView::Template::Error (wrong number of arguments (4 for 1..3)):
1: <%= select_tag :vehicle_model_id, options_for_select(#model_ids.map {|s| [s.model, s.first.id]}, nil), {}, {class: "form-control"} %>
Im stuck here. I dont know how to proceed from here.. please help
In your controller action update_models, you are trying to render js, so it's trying to find template named as update_models.js.erb.
You can try replacing your respond_to block with:
respond_to do |format|
format.json { render :json => #model_ids }
end
Afterwards, you will need to parse this data in your ajax success callback

Single model different view and CRUD functionality in RubyOnRails3

As a new to Ruby on rails, I stumble on a part of my app. I read the basics of RoR framework and know the 'convention over configuration' feature of rails MVC. I have two tables, one is apps_events and another is apps_events_attributes. The id of the first one is the foreign key of the second and in has many relationship. The app_events table has a field of foreign key attribute 'app_id', so selecting on a particular app I will be redirected to its events and attributes. There is also a field called 'is_standard' which actually distinguish the event type whether it's a Standard or Custom event.
Now I have to render those events and its attributes of a particular app in two different tab on the view layer with it's attributes using nested_form_for feature. User can toggle to Standard and Custom event through this tab click. Can anyone suggest me how will I achieve the same and can show me the ideal flow of this scenario (model name and checking part of 'is_standard', propagate the same in controller and render to the view)?
By the way, can I use different controller over the same model and if I do the same then is it capable of doing the same CRUD functionality for different Event and its attributes?
I have all it done alone and it is not very hard what I think at first, all trick is done by JQuery... and share the concept if somebody got same problem as me
My Models are
class AppsEvent < ActiveRecord::Base
belongs_to :app
has_many :apps_events_attributes, :foreign_key => 'apps_event_id',
:class_name => 'AppsEventsAttribute',
:dependent => :destroy
accepts_nested_attributes_for :apps_events_attributes,
:reject_if => lambda { |a| (a[:name].blank? && a[:description].blank?) },
:allow_destroy => true
validates_presence_of :description
validates_presence_of :name
validates_presence_of :code
validates_presence_of :apps_events_attributes, :message => "can't be empty"
end
and
class AppsEventsAttribute < ActiveRecord::Base
set_table_name :apps_events_attributes
belongs_to :apps_event, :foreign_key => 'apps_event_id'
attr_accessible :id, :apps_event_id, :name, :description, :attribute_type, :is_std, :created_at, :updated_at
def type
self.attribute_type
end
end
and My Controller is...
class AppsEventsController < ApplicationController
layout :layout_by_resource
before_filter :initialize_default_app
before_filter :check_permission
before_filter :load
def load
#app = current_user.find_app(params[:app_id])
#apps_events = AppsEvent.where(:app_id => #app.id)
#apps_event = AppsEvent.new
end
def index
#app = current_user.find_app(params[:app_id])
#default_app = App.default(current_user)
#apps_events = AppsEvent.where(:app_id => #app.id)
#apps_event_jsons = Hash.new
#apps_events.each do |app_event|
json = Hash.new
json['User_ID'] = 548741213
json['Session_ID'] = 2568639390
json['Action_Type'] = app_event.code
json['eventsData'] = {}
app_event.apps_events_attributes.each do |apps_event_attributes|
if (apps_event_attributes.attribute_type == 'Integer')
json['eventsData'][apps_event_attributes.name] = 1234
elsif (apps_event_attributes.attribute_type == 'Float')
json['eventsData'][apps_event_attributes.name] = 1234.23
else
json['eventsData'][apps_event_attributes.name] = 'abcd'
end
end
#apps_event_jsons[app_event.id] = json
end
end
def new
#apps_event = AppsEvent.new
#app = current_user.find_app(params[:app_id])
#apps_event.app_id = #app.id
#apps_event.apps_events_attributes.build
#action = 'create'
render 'edit'
end
def edit
#app = current_user.find_app(params[:app_id])
#apps_event = AppsEvent.find(params[:id])
#action = 'update'
end
def create
#apps_event = AppsEvent.new(params[:apps_event])
#show_custom_event = 'true'
#apps_event.name = #apps_event.name.strip
respond_to do |format|
if #apps_event.save
format.html {
redirect_to("/app/#{params[:apps_event][:app_id]}/apps_events",
:notice => "Successfully created #{#apps_event.name} custom definition.")
}
format.js {
flash[:notice] = 'Successfully created event.'
#apps_events = AppsEvent.where(:app_id => #app.id)
}
else
#app = current_user.find_app(params[:app_id])
if (#apps_event.apps_events_attributes == nil || #apps_event.apps_events_attributes.size <= 0)
#apps_event.apps_events_attributes.build
end
#apps_event.populate_code
#action = 'create'
format.html {
redirect_to("/app/#{params[:apps_event][:app_id]}/apps_events",
:alert => "Error in creating #{#apps_event.name} custom definition.")
}
format.js
end
end
end
def update
#apps_event = AppsEvent.find(params[:apps_event][:id])
params[:apps_event][:name] = params[:apps_event][:name].strip
respond_to do |format|
if #apps_event.update_attributes(params[:apps_event])
format.html {
if(#apps_event.is_std == 'y')
redirect_to("/app/#{params[:apps_event][:app_id]}/apps_events",
:notice => "Successfully updated #{#apps_event.name} standard definition.")
else
redirect_to("/app/#{params[:apps_event][:app_id]}/apps_events",
:notice => "Successfully updated #{#apps_event.name} custom definition.")
end
}
format.js {
flash[:notice] = 'Successfully updated event.'
#apps_events = AppsEvent.where(:app_id => #app.id)
render :nothing => true
}
else
#app = current_user.find_app(params[:app_id])
if (#apps_event.apps_events_attributes == nil || #apps_event.apps_events_attributes.size <= 0)
#apps_event.apps_events_attributes.build
end
#apps_event.populate_code
#action = "update"
format.html {
if(#apps_event.is_std == 'y')
redirect_to("/app/#{params[:apps_event][:app_id]}/apps_events",
:alert => "Error in updating #{#apps_event.name} standard definition.")
else
redirect_to("/app/#{params[:apps_event][:app_id]}/apps_events",
:alert => "Error in updating #{#apps_event.name} custom definition.")
end
}
format.js
end
end
end
def delete
if AppsEvent.delete(params[:id])
redirect_to "/app/#{params[:app_id]}/apps_events", :notice => "Successfully deleted #{#apps_event.name} custom definition."
else
redirect_to "/app/#{params[:app_id]}/apps_events",
:alert => "Error in deleting #{#apps_event.name} custom definition."
end
end
end
and I have 5 view files which are index.html.erb, edit.js.erb, _form_custom.html.erb, _form_standard.html.erb and _events.html.erb beside that have also a helper file for update, create and delete using ajax call by setting remote => true. In index file I am doing partial rendering all events(_events.html.erb) and here I done the trick :P
My _events.html.erb
<% for apps_event in #apps_events %>
<% if (apps_event.is_std == 'y') %>
<div class="standardEvent showStandard">
<ul>
<li class="column_1"><span style="font-weight: bold;"><%= apps_event.name %></span></li>
<li class="column_2"><span><%= apps_event.code %></span></li>
<li class="column_3"><span><%= apps_event.description %></span></li>
<li class="column_4">
<%= link_to edit_apps_event(apps_event) %>
</li>
<li class="column_5">
</li>
</ul>
</div>
<% else %>
<div class="customEvent showCustom" style="display:none">
<ul>
<li class="column_1"><span style="font-weight: bold;"><%= apps_event.name %></span></li>
<li class="column_2"><span><%= apps_event.code %></span></li>
<li class="column_3"><span><%= apps_event.description %></span></li>
<li class="column_4">
<%= link_to edit_apps_event(apps_event) %>
</li>
<li class="column_5">
<%= remove_apps_event_prompt_link(apps_event) %>
</li>
</ul>
</div>
<% end %>
<div class="clrBoth"></div>
<% end %>
now you can figure out the left part mean -- JQuery part to hide or show a div.

Resources