0

I'm trying to build an admin backend for a cms website.

this is the structure of my application

├── app.rb
├── Gemfile
├── models
│   └── models.rb
├── routes
│   └── routes.rb
└── views
    ├── categories.erb
    ├── # ... other view files

app.rb

require 'sinatra'
require 'data_mapper'
require 'dm-core'
require 'dm-migrations'
require 'digest'

enable :sessions

DataMapper.setup(:default, 'mysql://username:password@localhost/database')
require './models/models.rb' 
require './routes/routes.rb'
DataMapper.finalize

models.rb

class Category
  include DataMapper::Resource

  property :id,         Serial
  property :name,       String

  has n, :posts
end
# other model definitons

I've defined a categories route inside my routes.rb

...
get '/categories' do 
    @categories = Category.all
    erb :categories
end 
...

Contents of view (categories.erb) file.

                #table headers   
                <tbody>
                <% @categories.each do |c| %>
                    <tr>
                        <td>
                            <%= c.id %>
                        </td>
                        <td>
                            <%= c.name %>
                        </td>
                        <td>
                            <%= с.posts.count %>
                        </td>
                        <td>
                            <%= c.posts(:order => [:updated_at.desc]).first.updated_at.strftime("%d/%m/%Y") %>
                        </td>
                    </tr>
                <% end %>
                </tbody>

When I browse to /categories route, server spits this error

NameError at /categories
undefined local variable or method `с' for #<Sinatra::Application:0x0000000284bc08>

I have not faced such problem before. And really don't know what is going on.

The problem probably is not with application structure (the require sequences inside app.rb) because, before get '/categories' I've defined a post '/login' route which checks user inputs against database records. And it works as I want.

post '/login' do 
    email = params[:email]
    pwd = params[:password]

    user = Author.first(:email=>email)

    if user.nil?
        redirect to ('/register')
    elsif !user.nil?
        if Digest::MD5.hexdigest(pwd) == user.password
        ... #and so on

UPDATE

I'm listing other table/models with same methods, and all of them works as i expected, but categories.

other routes  
get '/articles' do 
    @articles = Post.all(:is_blog_post => false)
    erb :site_articles
end
##blog articles
get '/blogposts' do 
    @barticles = Post.all(:is_blog_post => true)
    erb :blog_articles
end
#users
get '/admin_users' do
    @admins = Author.all(:is_admin=>true)
    erb :admin_users 
end

#bloggers
get '/bloggers' do
    @bloggers = Author.all(:is_admin=>false)
    erb :blog_users 
end

and corresponding view files site articles

            <tbody>
            <% @articles.each do |art| %>
                <tr>
                    <td>
                        <%= art.title %>
                    </td>
                    <td>
                        <%= art.author.full_name %>
                    </td>
                    <td>
                        <%= art.category.name %>
                    </td>
                    <td>
                        <%= art.updated_at.strftime("%d/%m/%Y %H:%M") %>
                    </td>
                    <td>
                        <%= art.featured? ? "Yes" : "No" %>
                    </td>
                </tr>
                <% end %>
            </tbody>

blog articles

            <tbody>
            <% @barticles.each do |art| %>
                <tr>
                    <td>
                        <%= art.title %>
                    </td>
                    <td>
                        <%= art.author.full_name %>
                    </td>
                    <td>
                        <%= art.category.name %>
                    </td>
                    <td>
                        <%= art.updated_at.strftime("%d/%m/%Y %H:%M") %>
                    </td>
                    <td>
                        <%= art.featured? ? "Yes" : "No" %>
                    </td>
                </tr>
                <% end %>
            </tbody>

admins

            <tbody>
            <% @admins.each do |admin| %>
                <tr>
                    <td>
                        <%= admin.full_name %>
                    </td>
                    <td>
                        <%= admin.email %>
                    </td>
                    <td>
                        <%= !admin.twitter.nil? ? admin.twitter : "N/A" %>
                    </td>
                    <td>
                        <%= !admin.facebook.nil? ? admin.facebook : "N/A" %>
                    </td>
                    <td>
                        <%= !admin.phone.nil? ? admin.phone : "N/A" %>
                    </td>
                    <td>
                        <%= admin.posts.count %>
                    </td>
                </tr>
                <% end %>
            </tbody>

bloggers

                <tbody> 
                <% @bloggers.each do |blogger| %>
                    <tr>
                        <td>
                            <%= blogger.full_name %>
                        </td>
                        <td>
                            <%= blogger.email %>
                        </td>
                        <td>
                            <%= !blogger.twitter.nil? ? blogger.twitter : "N/A" %>
                        </td>
                        <td>
                            <%= !blogger.facebook.nil? ? blogger.facebook : "N/A" %>
                        </td>
                        <td>
                            <%= !blogger.phone.nil? ? blogger.phone : "N/A" %>
                        </td>
                        <td>
                            <%= blogger.posts.count %>
                        </td>
                    </tr>
                    <% end %>
                </tbody>
marmeladze
  • 6,468
  • 3
  • 24
  • 45
  • does it give a line number? – thesecretmaster Jul 26 '15 at 11:26
  • yes, `file: categories.erb location: block (2 levels) in singleton class line: 28` which corresponds to `<%= с.posts.count %>` the interesting is, i am able to list users with the same method inside another view file, but when attempting to list categories, program crashes. terminal output for the same script `> c.posts.count (# in newline) => 3 ` – marmeladze Jul 26 '15 at 11:42
  • Try running in terminal `irb app.rb`, then try the command `var = Catagories.all.posts`. Then try `var.count`. Please tell me what happens – thesecretmaster Jul 26 '15 at 11:53
  • before trying it, let me ask, `Category.all` will return an array which will include instances of `Category` class. I don't think this array will be able to respond `posts` method without errors. – marmeladze Jul 26 '15 at 12:06
  • You are doing that above: if `c = Catagories.all` then you are saying `Catagorey.all.posts.count` – thesecretmaster Jul 26 '15 at 12:08
  • maybe you've missed the iteration part. i've written` <% @categories.each do |c| %>` then for a single `c` instance, i called some attributes. – marmeladze Jul 26 '15 at 12:14

1 Answers1

5

You’ve somehow got an odd character in your source. That’s not a “normal” latin c in the line <%= с.posts.count %>, it’s U+0441, CYRILLIC SMALL LETTER ES. It just looks like a latin c.

To fix it just delete the character and re-write it with a normal c.

matt
  • 78,533
  • 8
  • 163
  • 197
  • 1
    I thought something like this could explain what you see, so I copied the line into irb, and then called `bytes` on it to check. Do you know how it got there – are you using Cryillic script elsewhere? – matt Jul 26 '15 at 13:15
  • yes, when i need need to write something in russian, i use cyrillic layout. and this picture may explain the situation. http://winrus.com/std_ru.gif :) C and С use same key. – marmeladze Jul 26 '15 at 13:21