Как я могу сделать СУХОЙ повторяющийся код, используемый в модельных методах и контроллерах в Rails 3? - PullRequest
1 голос
/ 02 мая 2011

У меня есть следующие методы для одной модели, и может быть больше.У меня также может быть часть повторяющегося кода в помощнике.Как я могу сделать его СУХИМ?

25   def full_name
 26     client = LinkedIn::Client.new(ENV['LINKEDIN_KEY'], ENV['LINKEDIN_SECRET'])
 27     client.authorize_from_access(self.atoken, self.asecret)
 28     client.profile(id => self.uid)
 29     client.profile.first_name + " " + client.profile.last_name
 30   end
 31 
 32   def image_url
 33     client = LinkedIn::Client.new(ENV['LINKEDIN_KEY'], ENV['LINKEDIN_SECRET'])
 34     client.authorize_from_access(self.atoken, self.asecret)
 35     client.profile(id => self.uid)
 36     client.profile(:fields => "picture-url").picture_url
 37   end

Код, в котором я создаю экземпляр клиента и в большинстве случаев обращаюсь к идентификатору профиля, повторяется каждый раз, когда мне нужно вызвать метод в API.Изменяется только API.

Что происходит, когда мне также необходимо вызвать контроллер (другой модели?)

29     if @review.save
 30       flash[:notice] = "Successfully created review."
 31       # check if allowed to post to LinkedIn and post
 32       if @review.post_linkedin?
 33         client = LinkedIn::Client.new(ENV['LINKEDIN_KEY'], ENV['LINKEDIN_SECRET'])
 34         client.authorize_from_access(current_user.atoken, current_user.asecret)
 35         debugger 
 36         client.update_network("has shared expertise on <a")
 37       end

Как сделать его более сухим?

Ответы [ 3 ]

1 голос
/ 02 мая 2011

Я согласен с @thekindofme, но я бы добавил некоторое кэширование, чтобы вам не приходилось каждый раз выполнять вызов API LinkedIn:

def linkedin_profile
  @linkedin_profile ||= set_linkedin_profile
end

def set_linkedin_profile
  client = LinkedIn::Client.new(ENV['LINKEDIN_KEY'], ENV['LINKEDIN_SECRET'])
  client.authorize_from_access(self.atoken, self.asecret)
  client.profile(id => self.uid)
  client.profile
end

def full_name
  linkedin_profile.first_name + " " + linkedin_profile.last_name
end

def image_url
  linkedin_profile(:fields => "picture-url").picture_url
end
0 голосов
/ 02 мая 2011

Я бы добавил следующие методы в ваш пользовательский класс:

class User
  def linkedin_client
    @linkedin_client || = get_linkedin_client 
  end

  def linkedin_profile
    linkedin_client.profile(id => self.uid)
    linkedin_client.profile
  end

  def full_name
    linkedin_profile.first_name + " " + user.linkedin_profile.last_name
  end

  def image_url
    linkedin_profile(:fields => "picture-url").picture_url
  end


  private

  def get_linkedin_client
    client = LinkedIn::Client.new(ENV['LINKEDIN_KEY'], ENV['LINKEDIN_SECRET'])
    client.authorize_from_access(atoken, asecret)   
    client     
  end
end

и внутри вашего контроллера вы бы написали:

if @review.save
  flash[:notice] = "Successfully created review."
  # check if allowed to post to LinkedIn and post
  if @review.post_linkedin?
    current_user.linkedin_client.update_network("has shared expertise on <a")
  end
end

Надеюсь, это поможет.

0 голосов
/ 02 мая 2011

Общее правило: извлекать код, который повторяется везде, помещать его в класс / метод многократного использования ... и т. Д.

для вышеуказанного кода. Вы могли бы сделать что-то вроде:

def get_client_profile
      client = LinkedIn::Client.new(ENV['LINKEDIN_KEY'], ENV['LINKEDIN_SECRET'])
      client.authorize_from_access(self.atoken, self.asecret)
      client.profile(id => self.uid)
      client.profile
end

def full_name
  p=get_client_profile
  p.first_name + " " + p.last_name
end

... и т.д.

В этом случае у вас может быть get_client_profile в вашей модели (может быть в модели Client?). Как «это принадлежит их».

...