Datamapper, Sinatra, Haml : attaching and rendering Comments from a post - ruby

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.

Related

Sinatra param filter

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

Sinatra dropdown list

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.

undefined method `capture_haml' for #<#<Class:0xbe53d68>:0xcf9cb24> in rails

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.

Using middleman, how do you include one HAML file in another HAML file?

I'm using middleman to do some rapid prototyping and can't for the life of me figure out how to include one HAML file into another HAML file.
I can include stuff in a layout file, but can't get one non-layout file to include another non-layout file. There are blocks of HTML that I want to reuse on some pages and I think I could do this. I've tried:
- render: partial=>"shared/nav.haml"
=shared/nav.html
="shared/nav.html
and none of these work.
Am I missing a config option or plugin? This is a fresh middleman install.
ANSWER
Partials may need file names that start with an underscore. My partial is placed in a folder called shared. The full name of the file is _nav.html.haml
This worked for me.
!= haml :"shared/_nav"
Example in context:
#email.main.subscriber.resize
#bg-wrap
%div
%img{:src=>"images/backgrounds/image.png",:alt=>""}
%section#zone10
!= haml :"shared/_nav"
You may also use the format specified in the approved answer below.
I've been using HAML with MiddleMan and couldn't be happier. Here is what is working for me:
I have a file: source/_donate_buttons.h
#DonationButtons
%p= t('searching.donate_cover_costs')
%br
= partial(:paypal_donate_button, :locals => {:amount => 1,
:amount_text => t('searching.donate_1')})
This uses the partial statement shown to include a file called source/_paypal_donate_button.html.haml.
And I include the _donate_buttons.html.haml file itself in a couple of places with:
= partial "donate_buttons"
though I think this could also be:
= partial :donate_buttons
I.e. I think partial is the magic you're looking for.
And, just for completeness, here is a slightly stripped down _paypal_donate_button.haml which shows how the paramaterization works there:
-btnclass = (locals.key?(:highlight) && locals[:highlight] ? "HighlightedDonationButton" : "DonationButton")
-btnstyle = locals.key?(:button_style) && locals[:button_style]
.DonationButtonContainer
%form{:action => "https://www.paypal.com/cgi-bin/webscr", :method => "post"}
%input{:name => "business", :type => "hidden", :value => "payments#example.com"}
%input{:name => "cmd", :type => "hidden", :value => "_donations"}
%input{:name => "amount", :type => "hidden", :value => "#{amount}.00"}
%input{:name => "currency_code", :type => "hidden", :value => "USD"}
%input{:class => btnclass, :alt => t('paypal.alt_text'),
:style => "cursor: pointer; font-size: 18px; #{btnstyle}", :type => "submit", :value => amount_text}
Fwiw, I don't think the file needs to be _filename.html.haml and can instead be _filename.haml. Also, I'm localizing these, so ignore the t('tagname') and just put strings there. (I didn't want to introduce an error copy-pasting the examples so I left them in there.)
Hope this helps!

Ruby on Rails - Truncate to a specific string

Clarification: The creator of the post should be able to decide when the truncation should happen.
I implemented a Wordpress like [---MORE---] functionality in my blog with following helper function:
# application_helper.rb
def more_split(content)
split = content.split("[---MORE---]")
split.first
end
def remove_more_tag(content)
content.sub(“[---MORE---]", '')
end
In the index view the post body will display everything up to (but without) the [---MORE---] tag.
# index.html.erb
<%= raw more_split(post.rendered_body) %>
And in the show view everything from the post body will be displayed except the [---MORE---] tag.
# show.html.erb
<%=raw remove_more_tag(#post.rendered_body) %>
This solution currently works for me without any problems.
Since I am still a beginner in programming I am constantly wondering if there is a more elegant way to accomplish this.
How would you do this?
Thanks for your time.
This is the updated version:
# index.html.erb
<%=raw truncate(post.rendered_body,
:length => 0,
:separator => '[---MORE---]',
:omission => link_to( "Continued...",post)) %>
...and in the show view:
# show.html.erb
<%=raw (#post.rendered_body).gsub("[---MORE---]", '') %>
I would use just simply truncate, it has all of the options you need.
truncate("And they found that many people were sleeping better.", :length => 25, :omission => '... (continued)')
# => "And they f... (continued)"
Update
After sawing the comments, and digging a bit the documentation it seems that the :separator does the work.
From the doc:
Pass a :separator to truncate text at a natural break.
For referenece see the docs
truncate(post.rendered_body, :separator => '[---MORE---]')
On the show page you have to use gsub
You could use a helper function on the index page that only grabs the first X characters in your string. So, it would look more like:
<%= raw summarize(post.rendered_body, 250) %>
to get the first 250 characters in your post. So, then you don't have to deal w/ splitting on the [---MORE---] string. And, on the show page for your post, you won't need to do anything at all... just render the post.body.
Here's an example summarize helper (that you would put in application_helper.rb):
def summarize(body, length)
return simple_format(truncate(body.gsub(/<\/?.*?>/, ""), :length => length)).gsub(/<\/?.*?>/, "")
end
I tried and found this one is the best and easiest
def summarize(body, length)
return simple_format = body[0..length]+'...'
end
s = summarize("to get the first n characters in your post. So, then you don't have to deal w/ splitting on the [---MORE---] post.body.",20)
ruby-1.9.2-p290 :017 > s
=> "to get the first n ..."

Resources