I am working on deleting a branch of a company using rails ajax.
Simple form for company account is -
= simple_form_for #company_account, :remote => true,
:url => company_account_path,
:method => :put do |f|
using this form i am creating, updating and deleting regions and branches of regions.
%div{ :id => 'branches_' + r.id.to_s}= render 'branches',f: f, r: region, company_account: #company_account
relation between company, region and branch is:
company has_many: regions
region belong_to: company
regions has_many: branches
branches belongs_to: regions
In this form i have a partial for displaying regions and branches, which uses form object of company account f. All this is working fine. I'm able to create new regions branches. Now i'm trying to delete branch using ajax.
When this call goes to controller i'm creating a form object for company account to render a partial like - In my controller
#f = view_context.simple_form_for #company_account, :remote => true,
:url => company_account_path,
:method => :put do |f|
render_to_string(:partial => 'company_accounts/branches', :locals => {f: f, r: #region, company_account: #company_account }).html_safe
end
and passing this #f object in responce using javascript as -
$('#branches_' + <%= #region.id%>).html('<%= escape_javascript #f %>');
$('#branches_' + <%= #region.id%>).show();
But unfortunately in response i am getting error -
undefined method `capture_haml' for #<#<Class:0xbe53d68>:0xcf9cb24>
Don't know what i am missing. Can any one please help??
Thanks in advance.
Update:
This is the Backtrace:
ActionView::Template::Error (undefined method `capture_haml' for #<#<Class:0xb9db2a4>:0xc953560>):
1: #inactive_branches
2: = f.simple_fields_for :regions, r do |reg|
3: %table.preferenceDetails
4: %tr
5: %td
app/views/company_accounts/_inactive_branches.html.haml:2:in `_app_views_company_accounts__inactive_branches_html_haml___356774371_104988750'
app/controllers/company_accounts_controller.rb:129:in `block in branches'
app/controllers/company_accounts_controller.rb:122:in `branches'
I fixed this issue by another way.
I am rendering a main partial of regions, in which form for #company account is created. Then kept both active/inactive branches partials in _regions.html.haml adding a condition on it.
When page is loaded it shows active branches by default and on the basis of request sent to show inactive branches then inactive branches partial is rendered.
Related
I am about to finnish my Sinatra Haml School project but I need a couple of things to get solved (I tried really hard but cannot solve the issues). I have a Software portfolio CMS where I can create new software entries (Title, Description, Language and Github link), being language a dropdown list filled from the database. Thing is I want to let the user select a filter from the list and filter by categories in the software list, but when I press the filter button it only shows the first entry. Here's the code in app.rb
get '/softwares/:filter' do
halt(404,'Forbidden') unless session[:admin]
#sware = Software.all
#categ = Category.all
haml :sware
end
post '/softwares/:filter' do
#sware = Software.find(category: params[:category])
haml :sware
end
And here is the HAML code that shows the list of softwares
%form{:action => "/softwares/:filter", :method => "post", :role => 'form'}
%select{:name => "category"}
- #categ.to_a.each do |category|
%option= category.name
%input{:type => "submit", :value => "Filter", :class => "btn"}
%ul.list
- #sware.each do |software|
%li(class="glyphicon glyphicon-search" aria-hidden="true")
%a{:href =>"/software/edit/#{software.id}", :class =>"btn btn-lg btn-primary"}= software.title
%a.pull-right(href="/software/delete/#{software.id}" class="btn btn-lg btn-danger") Delete
%li(role="separator" class="divider") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Thanks a lot for your answers. I really appreciate every information you can provide about what am I doing wrong.
It is a bit hard to tell from your question because you don't provide much info, e.g. what ORM you are using.
Supposing you're using ActiveRecord:
Software.find(...)
#=> returns the first match
Software.where(...)
#=> returns all matches
Im glad you answered my question about my dev issue, I'll try to be more self-explanatory this time.
I have a main app.rb where I use several endpoints redirecting to my Sinatra Haml views.My project is about a Software Portfolio, so I have this class: Software, and Category, which relationship is: one software has one category, and a category has many softwares. In the form where you create a new Software entry, I put a dropdown list where you can choose between 3 different categories: Desktop, Web and App.
Until there, everything is going well. The thing is, when the Software list shows up, I want to put a dropdown list to filter by created categories (I already have the "add category" form with its Class) and I can't figure out how to add the filter within a Filter button in the software list form. Can you guys help me please? Of course I know how to put the button there, but I want to show only the software entries where the selected category matches. Here's the list form.
%select{:name => "category"}
%option Desktop
%option Web
%option Device
%input{:type => "submit", :value => "Filter", :class => "btn"}
%ul.list
- #sware.each do |software|
%div{:class =>"list-group"}
%a{:href =>"/software/edit/#{software.id}", :class =>"btn btn-lg btn-primary"}
= software.title
%a.pull-right(href="/software/delete/#{software.id}" class="btn btn-lg btn-danger") Delete
Thanks a lot in advance!
You're calling the index method like this:
post '/all' do
index(:category)
end
You're passing an argument to the index call, but the index method doesn't take any arguments.
Please include the full error with your question.
index action can be DRY'ed:
def index
category = case
when params[:Web] then :Web
when params[:Desktop] then :Desktop
when params[:Device] then :Device
end
#sware = Software.title.where(categorization: { Software.categorization => category })
end
"It just doesn't work" is not a good place to start investigation of the problem. More debug information is required.
Beside the point that #max pleaner made, you're not actually calling the right object in params. It should be params[:category] and you should be able to rewrite that much simpler:
get '/all' do
halt(401,'Not Authorized, please login to continue') unless session[:admin]
#sware = Software.all
haml :sware
end
post '/:category' do
#sware = Software.title.where(categorization: {Software.categorization => params[:category]}
haml :index # assuming index.haml is where you want to go
end
Then, assuming your file is properly indented, your Haml file should work as well:
%select{:name => 'category'}
%option Desktop
%option Web
%option Device
%input{:type => 'submit', :value => 'Filter', :class => 'btn'}
%ul.list
- #sware.each do |software|
%div{:class =>'list-group'}
%a{:href =>"/software/edit/#{software.id}", :class =>'btn btn-lg btn-primary'}
= software.title
%a.pull-right{:href=>"/software/delete/#{software.id}" :class=>'btn btn-lg btn-danger'} Delete
Of course, the more information you can provide, the better the problem can be understood.
Not exactly sure of what to call this issue. Still new to rails.
Situation: An auction contains many lots.
I'm showing an auction's lots in a url like /auctions/3/lots/.
View:
<ul>
<% #lots.each do |lot| %>
<li><%= lot.auction_id %>: <%= lot.id %></li>
<% end %>
</ul>
Outputs this:
<ul>
<li>3: 1</li>
<li>3: </li>
</ul>
I only have one lot in my database. Not sure where the extra loop instance is coming from.
This happens on any lot listing no matter which auction I'm looking at.
Also,
<%= #lots.length %> displays 2
<%= #lots.size %> displays 2
<%= #lots.count %> displays 1
My lots_controller looks like this:
def index
#auction = Auction.find(params[:auction_id])
#lots = #auction.lots
end
def create
#auction = Auction.find(params[:auction_id])
#lot = #auction.lots.build(params[:lot])
if #lot.save
redirect_to auction_lots_path, :notice => 'Lot was successfully created.'
else
render :action => "index"
end
end
My models:
class Auction < ActiveRecord::Base
...
has_many :lots
end
class Lot < ActiveRecord::Base
belongs_to :auction
...
end
The ...s are just attr_accesssible and validates lines.
The log when I hit the page was requested, here it is.
Started GET "/auctions/8/lots" for 127.0.0.1 at 2013-02-13 16:35:51 -0500
Processing by LotsController#index as HTML
Parameters: {"auction_id"=>"8"}
Auction Load (0.1ms) SELECT "auctions".* FROM "auctions" WHERE "auctions"."id" = ? LIMIT 1 [["id", "8"]]
Lot Load (0.2ms) SELECT "lots".* FROM "lots" WHERE "lots"."auction_id" = 8
[#<Lot id: 18, description: "1923 Morgan", lot_number: 1, auction_id: 8, created_at: "2013-02-13 17:20:04", updated_at: "2013-02-13 17:20:04">]
Rendered layouts/_messages.html.erb (0.1ms)
Lot Exists (0.2ms) SELECT 1 AS one FROM "lots" WHERE "lots"."auction_id" = 8 LIMIT 1
Rendered lots/index.html.erb within layouts/application (9.4ms)
Completed 200 OK in 21ms (Views: 17.8ms | ActiveRecord: 0.5ms)
Update:
Someone mentioned that it looks like I'm using #auction.lots.build somewhere.
And yes, I am. I have a form on the same page (index) where I can add lots.
<%= form_for(#auction.lots.build, :url => auction_lots_path(#auction)) do |f| %>
...
<% end %>
Changing #auction.lots.build got rid of the extra row, although now I can't create lots successfully. I'm not sure what to do. I probably have to set up something in the index method of the lots_controller, but I don't know what.
Any help is appreciated.
This would happen in your create method if the lot failed to save. Because you used #auction.lots.build, that appends a lot record to the auction. If it doesn't save properly, it's still there unsaved. That explains why the "mystery" one doesn't have an id, and also why:
<%= #lots.size %> displays 2
<%= #lots.count %> displays 1
#lots.count is a database query, but #lots.size is just the size of the array in memory.
I would probably do something more like this in the create action:
def create
#auction = Auction.find(params[:auction_id])
#lot = #auction.lots.create!(params[:lot])
redirect_to auction_lots_path, :notice => 'Lot was successfully created.'
rescue ActiveRecord::RecordInvalid
render :action => "index"
end
... but of course others will prefer using if/else rather than rescuing the exception. There are other ways around this. You could do #auction.reload.lots to cull the unsaved one, but that's a little wierd. The normal rails thing to do in this case is re-render the form with the validation errors displayed and ask the user to fix them and try creating again.
This should help:
def create
params[:lot].merge!({:auction_id => params[:auction_id]})
#lot = Lot.new(params[:lot])
if #lot.save
redirect_to auction_lots_path, :notice => 'Lot was successfully created.'
else
render :action => "index"
end
end
I'm working with a model that I know is working (records exist in the data base, can be searched for and displayed in other views, etc.) but when I try to use the form_for tag to generate a view for editing one of these records, I get an error message:
Showing /var/www/caucus/app/views/registration_loader/checkIn.html.erb where line #13 raised:
undefined method `voter_path' for #<#<Class:0x98cabdc>:0x98c8878>
Extracted source (around line #13):
10: </div>
11:
12: <%= form_for(
13: #voter,
14: { :controller => "registration_loader",
15: :action => "editVoter"
16: } ) do |f| %>
The #voter refers to a Voter object retrieved by:
# Get the voter.
#voter = Voter.where( [ "voter_id = ?", #voterId ] )[ 0 ]
if not #voter
flash[ :error ] = "NO VOTER!"
redirect_to :action => 'search'
elsif not #voter.kind_of?( Voter )
flash[ :error ] = "NO VOTER RECORD! (#{#voter.class.to_s})"
redirect_to :action => 'search'
end
When I change the #voter to :voter, it stops giving me the error, but does not populate the fields in my view with the data for the record I want to edit.
According to the Rails 3.1 API guide, passing a model object into form_for should generate code that allows me to edit the data in that object, but evidently there is a missing helper method (voter_path). Where is this voter_path method supposed to be defined, and what is its proper semantic and signature? Nowhere in the documentation is creating such a method discussed, nor can I find any examples of writing such a method.
Is the *_path method supposed to be auto-generated? If not, can someone point me to the documentation that specifies the syntax and semantics of this method?
Thanks,
John S.
Short answer: don't use form_for unless you have also designed your code to use "resourceful controllers". Use form_tag instead. Adding resources :voters to routes creates routes to a non-existent controller.
I have a model Ticket which has n Comments belonging to it (many to one relationship).
The issue is that I can not render any of the comments nor does the form post the comments to the database.
I can kinda sorta do this from irb. I can add comments to tickets.comments, but I cannot pull individual comments - I can pull up the collection but have not figured out how to do anything with it. It is a Class: DataMapper::Associations::OneToMany::Collection and documentation says "A Collection should act like an Array in every way"
So 2 issues needing reading and input:
1) posting from the web form
2) iterating over and rendering the collection through haml, which I can't seem to do.
More gory details:
I have a Sinatra method that pulls up
get '/:thisticket' do
#ticket=Ticket.first(:slug=>params[:slug])
if #ticket
haml :showticket
Haml template
%div{:class => "ticket"}
%h1
= #ticket.slug
= #ticket.comments.all (returns the # symbol to any html page)
- #ticket.comments.all do |comment|
%h4
= comment.a_comment
%h4
= comment.created_at
%h4
= comment.id (this block shows nothing on a rendered page)
%center
%form{:action => "/#{#thisticket.slug}/update", :enctype => "text/plain", :method => "post"}
comments
%br/
%textarea{:id => "a_comment",:name => "a_comment", :rows => "5"}
:preserve
%br/
%input{:type => "submit", :value => "post"}/
For anyone paying attention or having the same:
This works
Sinatra
get '/:thisticket' do
#ticket=Ticket.first(:thisticket=>params[:thisticket])
#comments=#ticket.comments.all(:order => [ :created_at.desc ])
if #ticket
haml :showticket
Haml
#comments.each do |comment|
comment.comment
etc, etc, et. al.